解读Javascript中的Function.prototype.bind

首先贴上MSDN上标准的Polyfill:

 1 if (!Function.prototype.bind) {
 2   Function.prototype.bind = function(oThis) {
 3     if (typeof this !== 'function') {
 4       // closest thing possible to the ECMAScript 5
 5       // internal IsCallable function
 6       throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
 7     }
 8 
 9     var aArgs   = Array.prototype.slice.call(arguments, 1),
10         fToBind = this,
11         fNOP    = function() {},
12         fBound  = function() {
13           return fToBind.apply(this instanceof fNOP
14                  ? this
15                  : oThis,
16                  aArgs.concat(Array.prototype.slice.call(arguments)));
17         };
18 
19     if (this.prototype) {
20       // Function.prototype doesn't have a prototype property
21       fNOP.prototype = this.prototype; 
22     }
23     fBound.prototype = new fNOP();
24 
25     return fBound;
26   };
27 }

下面将上述代码逐行分析。

第一行判断Function的原型中是否有该函数, 因为bind函数并不是每个浏览器都支持,下面列出浏览器的支持情况:

 

  

第3行 if (typeof this !== 'function')用来判断调用bind函数的对象是否为函数,注意在整个bind函数作用域中this指代调用它的对象,且该对象必须为函数,通过typeof函数来检测。

第9行var aArgs = Array.prototype.slice.call(arguments, 1)中,arguments为传入bind函数的参数对象,由于其并不是数组,而是一种伪数组对象,但是可以使用数组的slice方法,由于bind函数的第一个参数为绑定的函数,故slice方法从1开始获取参数。  

  举例: someFunc.bind(oThis, arg1, arg2) ,则slice方法取到的就是[arg1, arg2]。

第12行fBound函数,为最终bind函数返回的新函数,通过apply方法将fToBind函数的上下文改为oThis。

第16行 aArgs.concat(Array.prototype.slice.call(arguments))),这行代码将bind函数中的参数和执行bind函数返回的函数传入的参数进行合并,最终传给实际调用的函数fToBind来使用。

第21行 fNOP.prototype = this.prototype; 将fToBind中的原型对象赋给一个没有原型的空函数,再通过fBound.prototype = new fNOP(); 进行原型函数继承,因为apply方法只能继承构造方法,最终返回的fBound匿名函数继承了fToBind对象的构造方法和原型方法,且上下文为oThis,从而实现了绑定。

实际上 anotherFunc =someFunc.bind(oThis, arg1, arg2);中的anotherFunc即为fBound, anotherFunc(args)即执行fBound(args)。 

转载于:https://www.cnblogs.com/ysy32020/p/6809824.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值