bind()函數是在 ECMA-262 第五版才被加入;它可能無法在所有瀏覽器上運行。這就需要我們自己實現bind()函數了 簡單實現bind()方法: 考慮到函數柯里化的情況,我們可以構建一個更加健壯的bind(): 這次的bind()方法可以綁定對象,也支持在綁定的時候傳參。 繼續,Javasc ...
bind()
函數是在 ECMA-262 第五版才被加入;它可能無法在所有瀏覽器上運行。這就需要我們自己實現bind()
函數了
簡單實現bind()
方法:
Function.prototype.bind = function(context){ self = this; //保存this,即調用bind方法的目標函數 return function(){ return self.apply(context,arguments); }; };
考慮到函數柯里化的情況,我們可以構建一個更加健壯的bind()
:
Function.prototype.bind = function(context){ var args = Array.prototype.slice.call(arguments, 1), self = this; return function(){ var innerArgs = Array.prototype.slice.call(arguments); var finalArgs = args.concat(innerArgs); return self.apply(context,finalArgs); }; };
這次的bind()
方法可以綁定對象,也支持在綁定的時候傳參。
繼續,Javascript的函數還可以作為構造函數,那麼綁定後的函數用這種方式調用時,情況就比較微妙了,需要涉及到原型鏈的傳遞:
Function.prototype.bind = function(context){ var args = Array.prototype.slice(arguments, 1), F = function(){}, self = this, bound = function(){ var innerArgs = Array.prototype.slice.call(arguments); var finalArgs = args.concat(innerArgs); return self.apply((this instanceof F ? this : context), finalArgs); }; F.prototype = self.prototype; bound.prototype = new F(); retrun bound; }
這是《JavaScript Web Application》一書中對bind()
的實現:通過設置一個中轉構造函數F,使綁定後的函數與調用bind()
的函數處於同一原型鏈上,用new操作符調用綁定後的函數,返回的對象也能正常使用instanceof,因此這是最嚴謹的bind()
實現。
對於為了在瀏覽器中能支持bind()
函數,只需要對上述函數稍微修改即可:
Function.prototype.bind = function (oThis) { if (typeof this !== "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 () { return fToBind.apply( this instanceof fNOP && oThis ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments)) ); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; };