call apply 作用
在JavaScript里面,call、apply的作用是改变函数内this的指向。不用点是,call是直接传参数,apply是参数要放数组内。
注:在函数内this是指调用函数的调用方
使用示例
let cat = {
name: "Tom",
say: function (age) {
console.log(`My name is ${this.name}. I'm ${age} year old.`)
}
}
cat.say(13);
let dog = {
name: "Jack"
}
// 直接传参数
cat.say.call(dog, 14);
// 参数要放数组内
cat.say.apply(dog, [15]);
// 输出
// My name is Tom. I'm 13 year old.
// My name is Jack. I'm 14 year old.
// My name is Jack. I'm 15 year old.
手写call apply
思路:
- 新建一个Function原型函数,
- 给传进来新的调用方添加方法属性
- 调用新的方法属性
- 返回值
代码示例:
Function.prototype.myCall = function (caller, ...args) {
// caller 为空的时候指向全局window对象
caller = caller ? caller : window;
// 新建一个属性名,为了不和已有属性冲突使用Symbol
let tempKey = Symbol();
// 给caller添加方法属性
caller[tempKey] = this;
// 透传参数调用新的方法属性
let res = caller[tempKey](...args);
// 清理添加的方法属性
delete caller[tempKey];
// 透传返回值
return res;
}
cat.say.myCall(dog, 16);
Function.prototype.myApply = function (caller, [...args]) {
// caller 为空的时候指向全局window对象
caller = caller ? caller : window;
// 新建一个属性名,为了不和已有属性冲突使用Symbol
let tempKey = Symbol();
// 给caller添加方法属性
caller[tempKey] = this;
// 透传参数调用新的方法属性
let res = caller[tempKey](...args);
// 清理添加的方法属性
delete caller[tempKey];
// 透传返回值
return res;
}
cat.say.myApply(dog, [17]);
// 输出
// My name is Jack. I'm 16 year old.
// My name is Jack. I'm 17 year old.