apply, call, bind的原理和区别;用apply来实现bind

133 阅读2分钟

apply call bind区别

apply用法:

    var targetObj={
        name:"targetName",
        age:11
    }
    function fun(addFirstNumber,addSecondNumber){
        console.log(this.age+addFirstNumber+addSecondNumber);
    }
    fun.apply(targetObj,[1,1]);
    
    返回结果:
    13

call 用法:

   var targetObj={
        name:"targetName",
        age:11
    }
    function fun(addFirstNumber,addSecondNumber){
        console.log(this.age+addFirstNumber+addSecondNumber);
    }
    fun.call(targetObj,1,1);
    
    返回结果:
    13

bind用法:

  var targetObj={
        name:"targetName",
        age:11
    }
    function fun(addFirstNumber,addSecondNumber){
        console.log(this.age+addFirstNumber+addSecondNumber);
    }
    fun.bind(targetObj,1,1)();
    
    返回结果:
    13

三者区别:

1,apply,call会改变this指向并且函数会立即调用,返回值为函数调用的结果,bind也会改变this指向,函数不会立即调用,返回结果为改变了this指向的函数。

2,apply只传入两个参数,第一个参数是this要指向的对象,第二个参数函数要传入的参数,。call可以传入多个参数,第一个参数也是this指向的对象,后面的参数都为原函数要传入的参数。bind可以传入多个参数,第一个参数为this要指向的对象,剩余参数为函数调用传入参数。

当我们使用一个函数需要改变this指向的时候才会用到call,apply,bind

如果你要传递的参数不多,则可以使用fn.call(thisObj, arg1, arg2 ...)

如果你要传递的参数很多,则可以用数组将参数整理好调用fn.apply(thisObj, [arg1, arg2 ...])

如果你想生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用bind

apply call bind实现原理

apply实现:

 var targetObj={
        name:"targetName",
        age:11
    }
    function fun(addFirstNumber,addSecondNumber){
        console.log(this.age+addFirstNumber+addSecondNumber);
    }

    Function.prototype.myApply= function(obj,obj2){
        obj.fun=this;
        var result=eval('obj.fun('+obj2+')');
        delete obj.fun;
        return result;
    }
    fun.myApply(targetObj,[11,7])

call实现

var targetObj={
        name:"targetName",
        age:11
    }
    function fun(addFirstNumber,addSecondNumber){
        console.log(this.age+addFirstNumber+addSecondNumber);
    }

    Function.prototype.myCall= function(obj){
        obj.fun=this||window;
        var args=[];
        for(var i=1;i<arguments.length;i++){
            args.push(arguments[i]);
        }
        var result=eval('obj.fun('+args+')');
        delete obj.fun;
        return result;
    }
    fun.myCall(targetObj,5,6)

用apply实现bind:

var targetObj={
    name:"targetName",
    age:11
}
function fun(addFirstNumber,addSecondNumber){
    console.log(this.age+addFirstNumber+addSecondNumber);
}
Function.prototype.myBind= function(obj){
    var myThis=this;
    var ars=[];
    for(var i=1;i<arguments.length;i++){
        ars.push(arguments[i])
    }
  return function(){
      myThis.apply(obj,ars);
  }
}
fun.myBind(targetObj,7,8)();