引子
let obj = {
a: 1,
b: function () {
console.log(this);
},
};
obj.b(); //{a: 1, b: ƒ}
这样我们就知道,谁调用,这个this指向谁,我们可以利用这个特点
让想要指向的那个对象,变成直接调用者
比如有个
function a(){
console.log(this)//window
}
我有一个对象obj
我想让a函数里面的this指向obj
我们就要想办法让obj里面有一个属性,这个属性承载着a()
obj{
key:a(){
}
}
这就是改变this最终的解决方案
代码实现
//为每一个函数提供一个myCall方法
Function.prototype.myCall = function (thisArg, ...args) {
//给thisArg加一个一定和原属性不重名的新属性
const key = Symbol("key");
//不能直接.key因为这样不是动态的了,就是写死的了
thisArg[key] = this; //这个this是谁调用myCall就指向谁。所以this是func
//然后我们调用func
// thisArg[key]();
/*
person={
name:"lsw",
key:func(){
console.log(this);
console.log(numA, numB);
return numA + numB;
}
}
*/
//通过上面注释代码,func的this就指向了调用它的person
// console.log(args); //[2,4]注意args拿到的是一个数组
//接收剩余参数传给原函数
const res = thisArg[key](...args);
/*
const res = person.key(...args);将2,4传递给numA,numB
const res= func(numA,numB){
return numA+numB;
}
*/
//把动态添加的key属性删掉
delete thisArg[key];
return res;
};
//------------------------ 测试代码---------------------------
const person = {
name: "zs",
};
function func(numA, numB) {
console.log(this); //{name: 'lsw', f: ƒ}
console.log(numA, numB); //2,4
return numA + numB;
}
//我们要将func的this指向person
const res = func.myCall(person, 2, 4);
console.log("返回值为:", res);//6