手写JavaScript call apply方法

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

思路:

  1. 新建一个Function原型函数,
  2. 给传进来新的调用方添加方法属性
  3. 调用新的方法属性
  4. 返回值

代码示例:

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.

猜你喜欢

转载自blog.csdn.net/ouchangjian/article/details/126425333
今日推荐