call、apply、bind

call、apply:https://github.com/mqyqingfeng/Blog/issues/11
bind:https://github.com/mqyqingfeng/Blog/issues/12

call(不给对象新添加这个方法)

给一个函数指定this指针和参数值,调用这个函数

var foo = {
    value: 1
};
function bar() {
    console.log(this.value);
}
bar.call(foo); // 1

1、call 改变了 this 的指向,指向到 foo 2、bar 函数执行了

模拟实现的主要步骤:

  • 将函数设为对象的属性:foo.fn = bar
  • 执行该函数:foo.fn()
  • 删除该函数:delete foo.fn
 Function.prototype.call2 = function (obj) {
    // 处理obj为null的情况,这个时候指针指向window
    const context = obj || window;
    // 首先要获取调用call的函数,用this可以获取,谁调用call2就会获取到谁
    context.fn = this;
    const arr = [...arguments];
    // 去除第一个obj的值,从第二个取到最后
    const args = arr.slice(1);
    // 处理函数有返回值的情况
    const result = context.fn(...args);
    delete context.fn;
    return result;
  };
  }
apply(不给对象新添加这个方法)

1、给一个函数指定this指针和参数值 2、调用这个函数
与上面call基本一致,只是fn方法调用时,传入的是数组

Function.prototype.apply2 = function (obj) {
    // 处理obj为null的情况,这个时候指针指向window
    const context = obj || window;
    // 首先要获取调用call的函数,用this可以获取,谁调用call2就会获取到谁
    context.fn = this;
    const arr = [...arguments];
    // 去除第一个obj的值,直接取第二个值,就是一个数组,即为参数
    const args = arr[1];
    console.log('args', ...args)

    // 处理函数有返回值的情况
    const result = context.fn(...args);
    delete context.fn;
    return result;
  };
bind
Function.prototype.bind = function (obj) {
    const self = this;
    const args = [...arguments];
    const arr = args.slice(1);
    const fun = function() {}
    fun.prototype = self.prototype;
    const fn = function() {
      // new时会改变指针的方向,即如果他是构造函数,那么他的this指针就不指向obj,
      // 直接返回this,爱指哪指哪,否则指针指向obj
      // 只要判断当前的this指针的instanceof是否指向fn.prototype即可
      // bind只改变了函数的this指向,但是并没有改变他的原型链
      // 因此new实例时实在原型链上做查询,而不是直接在this上查询,
      //即绑定的obj没有效果(这个只是改变当前的this指向),参数传过来的值有效果
      // 会在原有的原型链上做查询,如果,查询的到,那么表示是new出来的实例,否则就是正常绑定的函数,这个时候this指向window
      const arr1 = arr.concat([...arguments]);
      return self.apply(this instanceof fun ? this : obj, arr1)
    }
    // 下面的那行代码相当于这个,fn.prototype = this.prototype;
    fn.prototype = new fun();
    return fn;
  };

你可能感兴趣的:(call、apply、bind)