call,apply,bind 的应用与源码实现

2020-05-12  本文已影响0人  泰然自若_750f

前端面试常见问题日常总结。
1:call ,apply,bind 相同点和不同点。
相同点:都是用来改变函数指向。
不同点:call 和 apply 都是立即执行,bind 不是立即执行。
call 和apply 的区别:call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组。call的性能更高一些

 function add(c, d){ 
    return this.a + this.b + c + d; 
}
var obj={a:1,b:2};
var a=10,b=20;// window 下的 a,b
//先执行 add
add(5,6); //41
//使用 call
add.call(obj,5,6);//14  
add.apply(obj,[5,6]);//14,传参是数组
var m=add.bind(obj,5,6); //不是立即执行  
m();//14
add.bind(obj,5,6)() //14

源码实现

 Function.prototype._call=function()
     {
         //获取需要更换的 this
         var context=Array.prototype.shift.call(arguments,1);
         context=context|| window;
         var func=this;
         context[func.name]=func;
         //执行
         let res=context[func.name](arguments);
         //执行完成后删除
         delete context[func.name];
         return res;
     }
 Function.prototype._apply=function()
     {
         //获取需要更换的 this
         var context=Array.prototype.shift.call(arguments,1);
         
         context=context|| window;
         var func=this;
         context[func.name]=func;
         if(!(arguments[0] && Array.isArray(arguments[0])))
         {
             throw new TypeError('arguments is not array');
         }
         //执行
         let res=context[func.name](arguments[0]?[...arguments[0]]:null);
         //执行完成后删除
         delete context[func.name];
         return res;
     }
 Function.prototype._bind=function(){
        var context=Array.prototype.shift.call(arguments,1);
        context=context|| window;
        var func=this;
        //返回一个函数
        return function(){
            var res=  func.call(context,arguments);
            return res;
        }

     }
 var a=1,b=2;

     function  add(c) {
         return (this.a+this.b+c);
     }
     var obj={a:3,b:4};
    add._call(obj,4);//11
    add._apply(obj,[4]);//11
    var _add=add._apply(obj);
   _add(4); //11

上一篇下一篇

猜你喜欢

热点阅读