实现call、apply和bind

实现call、apply和bind

三者的异同

  1. 都可以改变this指向。
  2. 接受的第一个参数为改变后的this指向。
  3. call、bind接受的参数,以队列的形式。apply接受数组形式的传参。
  4. call和apply可以多次改变this指向。而bind只可使用一次,再次使用无效,绑定的仍然是第一次的对象。
  5. call和apply调用时,会直接执行function,而bind会返回一个新的函数,且函数名为”bound xxx” 。

思路

在JavaScript中this的指向问题中提到,作为对象方法的调用。函数还可以作为某个对象的方法调用,这时this就指这个上级对象。也就是我们平时说的,谁调用,this就指向谁。

实现方法:在传入的参数中传入一个方法,然后执行这个方法,最后删除该方法(为了保持对象的前后一致性)。

实现

call

Function.prototype.newCall = function(context,...rest){
  //获取构造函数 即this
    const constructor = this;
  //获取对象 即新的this指向
  if(context){
      context = context || window;
  }else {
      context = Object.cerate(null);
  }
  //使用Symbol()确保不会覆盖对象obj的原有的属性
  const fn = Symbol();
  context[fn] = constructor;
  context[fn](...rest);
  //删除添加的属性
  delete context[fn]
}

const obj = {
    a:10,
    b:20,
    getMoney(){
        console.log(this.a)
    }
}

function fn(){
    console.log(this.a)
}
fn();//undefined
fn.newCall(obj);//10

apply

Function.prototype.newApply = function(context,rest){
  //获取构造函数 即this
    const constructor = this;
  //获取对象 即新的this指向
  if(context){
      context = context || window;
  }else {
      context = Object.cerate(null);
  }
  //使用Symbol()确保不会覆盖对象obj的原有的属性
  const fn = Symbol();
  context[fn] = constructor;
  context[fn](rest);
  //删除添加的属性
  delete context[fn]
}

const obj = {
    a:10,
    b:20,
    getMoney(){
        console.log(this.a)
    }
}

function fn(){
    console.log(this.a)
}
fn();//undefined
fn.newApply(obj);//10

bind

Function.prototype.newBind = function(context,...params){
    console.log(params)
    const Constructor = this;
    return function(...rest){
        Constructor.apply(context,[...params,...rest])
    }
}

const obj = {
    a:10,
    b:100
}

function fn(){
    console.log(this.a)
}

const f1 = fn.newBind(obj,1,2,3,4);

f1();//10
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!