bind apply call的区别及实现

参见https://blog.csdn.net/qq_40479190/article/details/78324270

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

http://www.ecma-international.org/ecma-262/6.0/ECMA-262.pdf

apply call bind 都是改变函数调用时this指向,apply call 会立即执行该函数,bind是返回绑定this指向后的函数,apply和call的区别是传入参数格式不同,apply接收数组,call接收参数列,实现apply 和call 方法

Function.prototype.call1 = function(obj,...rest){
     var self = this; //this即调用call方法的函数对象
     var context = Object(obj) || window
     context.fn = this
     return context.fn(...rest)
     //delete context.fn 
}

Function.prototype.call2 = function(obj){
     var self = this; //this即调用call方法的函数对象
     var context = Object(obj) || window
     context.fn = this
     var args = [];
     for(var i=1;i<arguments.length;i++){
        args.push('arguments['+i+']')
     }
     var result = eval('context.fn(' + args +')')
     delete context.fn 
     return result
}

function bar(a,n){
   console.log(a,"a")
   console.log(n,'n')
   return this.value

}

var obj = {value:90}

bar.call1(obj,2,'dfskj')

bind会创建一个新的函数,新函数的this被bind 的第一个参数指定,其余参数作为新函数调用时使用;

bind第一个参数:

1.调用bind函数时作为this参数传递给目标函数,如果对新函数使用new运算符,则忽略该值;

2.当使用bind在setTimeout中创建一个函数时,bind的第一个参数若为原始值,都将转换为Object;(在条件下原始只都会被转成Object)

3.如果bind 函数参数列表为空,执行作用域的this将被视为新函数的this;

绑定函数也可以使用new运算符构造,它会表现为目标函数已经被构建完毕了似的。提供的this值会被忽略,但前置参数仍会提供给模拟函数。

返回原始函数的拷贝,并拥有指定的this和参数

应用场景  创建偏函数(即带有指定参数的函数);指定确定this的函数

用call apply实现bind 方法 from MDN polyfill

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          // this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
          return fToBind.apply(this instanceof fBound
                 ? this
                 : oThis,
                 // 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    // 维护原型关系
    if (this.prototype) {
      // Function.prototype doesn't have a prototype property
      fNOP.prototype = this.prototype; 
    }
    // 下行的代码使fBound.prototype是fNOP的实例,因此
    // 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
    fBound.prototype = new fNOP();

    return fBound;
  };
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值