this
- 在函数执行时决定的不是定义时决定的
- this只和函数的调用有关*
obj.fn()中fn的this就是objarr[0] ()this就是arr
重定义
call
- 会直接执行函数
- 函数的参数逐个传进去

实现
- 首先先判断thisArg参数 如果为空就默认window 这里运用了
||运算符有一个t结果就为t 所以短路效果为前面的表达式结果为t 后面的表达式就不执行
补充说明
&&运算符前面一个f结果就为f 所以短路效果是前面为f后面不执行
- symbol(基本数据类型)有唯一性 可以保证属性与原对象不冲突
let key = Symbol('temp')创建一个symbol类型的变量key其中temp是这个变量的描述符 - 利用对象的方法中的this指向对象 :通过把这个函数给
thisArg对象的方法再通过这个对象调用就改变了函数this的指向 其中利用数组的展开运算符 把value(剩余参数数组)挨个传进这个方法完成了mycall改变this指向和直接执行函数的功能
js
//实现call
Function.prototype.myCall = function (thisArg, ...value) {
//如果参数为空 就默认是window
//利用||特性
thisArg = thisArg || window
let key = Symbol('temp')
thisArg[key] = this
//利用...数组的展开运算符把value的所有元素 逐个全部传入
thisArg[key](...value)
delete thisArg[key]
}
- 测试用例
js
//测试用例
//this指向对象
function fnCall(a, b) {
console.log(this, a, b);
}
fnCall.myCall(obj, 1, 2)
//this指向函数
function fn1() {
console.log('这是测试函数');
}
fnCall.myCall(fn1, 1, 2)
apply
- 也会直接执行函数
- 参数以对象(一般是数组的形式传进去)

实现
和mycall的基本思想是一样的区别如下
- 因为参数是数组形式 所以
myApply中的value参数不需要用剩余参数数组...value直接获取传入的数组value即可 然后还是使用...展开运算符把参数数组展开传入
js
//实现apply
Function.prototype.myApply = function (thisArg, value) {
thisArg = thisArg || window
let key = Symbol('temp')
thisArg[key] = this
//利用...数组的展开运算符把value的所有元素 逐个全部传入
thisArg[key](...value)
delete thisArg[key]
}
fnCall.myApply(obj, [1, 2])
- 测试用例同
mycall
bind
- 参数逐个传入
- 返回新数组 调用之后才执行(参数自动传进去 this改变)

实现
不会立即执行函数 而是返回新的函数
- 因为返回的新函数中的this就不是调用函数了 所以要把this放进fn函数里
- 返回一个新函数 先给
thisArg对象添加fn方法(就是要改变this的函数) 然后把原函数的返回结果 也就是对象方法的结果原函数的返回结果放进result作为新函数的返回结果 删除属性避免对原thisArg造成干扰 最后把result变量return出去
举例子(没有this干扰)理解
result变量的必要性这里把内部函数的返回值return出去 就能实现调用
outside函数返回一个inside函数并且把他的她的返回值也复制了最终代码
js
//实现bind
//创建新函数 this绑定到指定对象上
Function.prototype.myBind = function (thisArg, ...value) {
//不会立即执行函数 而是返回新的函数
thisArg = thisArg || window
let fn = this //把调用的函数存起来
return function () {
let key = Symbol('temp') //每次调用都创建新的临时键
thisArg[key] = fn
const result = thisArg[key](...value)
delete thisArg.fn
return result //返回原函数的执行结果
}
}
- 测试用例
js
//生成新的函数
function bindFn(a, b) {
console.log('myBind结果', this, a, b);
}
let Person = {
name: 'a'
}
const newBindfn = bindFn.myBind(Person, 2, 1)
//传入thisArg为空的情况
const newBindfn1 = bindFn.myBind('', 2, 3) //this指向window
//新生成的函数返回值
function fn() {
return '函数返回结果'
}
console.log(fn.myBind(Person)());//函数返回结果
这里把内部函数的返回值return出去 就能实现调用
最终代码