JS : call()、apply()、bind()源码解析,及它们的区别

call()
Function.prototype.newCall = function(){
    //将要使用的函数给要指向的target(相当于再target里面添加一个属性,这个属性名为fn,属性值为 this)
    var target = arguments[0] || windows
    target.fn = this;
    var args = [];
    for(var i = 1; i < arguments.length; i ++){
        args.push('arguments['+ i +']');
    }
    //执行target下fn这个属性 => target.fn(str);
    //eval()会直接将字符串作为表达式/函数进行执行
    var result = eval('target.fn(' + args.join(',')+')');
    
    //把创建的fn属性删除
    delete target.fn;
    return result;
}
复制代码
apply()
Function.prototype.newApply = function(target, arr){
    target = target || windows
    target.fn = this;
    //判断数组是否为空,如果为空直接执行。
     if(arr == []){
         return target.fn;
         delete target.fn;
     }else{
         var args = [];
         for(var i = 0; i < arr.length; i ++){
             args.push('arr['+ i + ']');
         }
         var result = eval('target.fn('+ args.join(',') +')');
         delete target.fn;
         return result;
     }
}
复制代码
call()apply()都是改变this的指向,它们之间只是是传参的形式不同。call()是字符串的形式,而apply()的第二个参数是数组的形式。
bind()
    var value = 0;
    var obj = {
        value : 123
    };
    function show(grade, name, age){
        console.log(this.value);
        console.log(grade, name, age);
        return name + age + value;
    }    
    Function.prototype.newBind = function(){
        var target = arguments[0] || window
        var self = this;
        //console.log(this)-->function show(){}
        
        //newBind 的形参数列表,去掉target。
        var args = [].slice.call(arguments,1);
        var temp = function(){};
        
        创建一个新函数 newFn
        var newFn = function(){
            //新函数的参数列表
            var _args = [].slice.call(arguments,0);
            
            //判断执行函数是否是构造函数执行的,是的话就用this,
            //若不是通过new的方式来执行,而是直接执行的话,就用target
            return self.apply(this instanceof temp ? this : target, args.concat(_args));
        }
        
        //让this(-->f show(){})和newFn形成关联,确保原型链不被破坏。
        temp.prototype = this.prototype;
        newFn.prototype = new temp();

        //返回新函数
        return newFn;
    }   
    var newShow = show.newBind(obj,'三年级');//'三年级' -> args
    newShow('kiwi', 18);// 'kiwi', 18 -> _args 
    //123
    //三年级 kiwi 18
复制代码
bind()call()/apply()的不同点简述
1)bind() 是返回一个新的函数。而 call()/apply() 绑定函数后直接执行,且每次执行都要重新绑定。
2)bind() 支持函数拥有预设的初始参数(即,'三年级'),这些参数会排在最前面,传给绑定函数的参数(即,'kiwi', 18)会跟在它们后面。复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值