call,apply,bind

71 阅读1分钟

call,apply,bind

js中,改变this指向的方法有三种。

  1. call()

    第一个参数,this的指向,之后的参数是传递给目标函数的参数,返回目标函数执行结果

  2. apply()

    同call()一样,第一个参数为this的指向,第二个参数是一个数组,数组中的值是传给目标对象的参数,返回目标函数执行结果。

  3. bind()

    参数与call()一样,第一个参数,this的指向,之后的参数是传递给目标函数的参数,返回值是确定this指向后的函数。

重写call()方法

重写call()方法的思路是,在目标对象(函数执行时要指定的this对象)的属性上注册目标函数,然后执行该函数,返回该函数的执行结果。

function fn(name) {
    this.name = name;
}
Function.prototype.call = function(context, ...params) {
    let self = this; //这个this就是函数实例,即调用call方法的函数
    let key = Symbol("key");
    context[key] = self; //使用 Symbol("key")作为属性名,避免污染原来对象上的属性
    let result = context[key](...params);
    delete context[key];
    return result;
};
let obj = {
    name: "rose",
};
fn.call(obj, "jack");
console.log(obj); //{name:"jack"},成功的将name改为了jack

重写bind()方法

重写bind()的思想就是 利用闭包的思想,返回一个函数。

    function fn(name) {
      console.log(this, name);
    }
    let obj = {
      name: "rose",
    };
    Function.prototype.bind = function(context, ...params) {
      // 对参数context进行处理,因为只有对象才具有属性
      let self = this;
      return function(...innerArgs) {
        self.call(context, ...params.concat(innerArgs));
      };
    };
    fn.bind(obj, "jack")();