试想当调用 call 的时候,把 foo 对象改造成如下:
var foo = {
value: 1,
bar: function() {
console.log(this.value)
}
};
foo.bar(); // 1
这个时候 this 就指向了 foo,但是这样却给 foo 对象本身添加了一个属性,我们用 delete 再删除它
所以将call实现原理归为以下三个步骤:
- 将函数设为对象的属性
- 执行该函数
- 删除该函数
Function.prototype.myCall = function (context) {
var context = context || window
context.fn = this // 将函数设为对象的属性
let arg = [...arguments].slice(1)
var result = context.fn(...arg) // 执行该函数
delete context.fn // 删除该函数
return result
}
var foo = {
value: 1
}
function bar(name) {
console.log(name)
console.log(this.value)
}
bar.myCall(foo, 2)