關於原生js中bind函數的實現


今天繼續研究了bind函數的實現,也知道了shim和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 internal IsCallable function
 5       throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
 6     }
 7 
 8     var aArgs = Array.prototype.slice.call(arguments, 1), 
 9         fToBind = this, 
10         fNOP = function () {},
11         fBound = function () {
12           return fToBind.apply(this instanceof fNOP && oThis
13                                  ? this
14                                  : oThis || window,
15                                aArgs.concat(Array.prototype.slice.call(arguments)));
16         };
17 
18     fNOP.prototype = this.prototype;
19     fBound.prototype = new fNOP();
20 
21     return fBound;
22   };
23 }

這是官方文檔上的實現,我分二個方面來談我要說的東西,

第一個是參數,agruments的使用

 var aArgs = Array.prototype.slice.call(arguments, 1),

這里是將bind函數的參數數組取出來,第一個參數不要(就是不要oThis)也就是要被綁定方法的那個對象,第二個是

aArgs.concat(Array.prototype.slice.call(arguments)));

 這里是用了數組的方法,把參數插在參數數組后面,要注意,這個函數是要被return 出去然后執行的,他的參數數組是return出去的那個fBound函數的參數數組,所以上下兩個參數數組是不一樣的,有點像柯里化。

 

第二個是上下文,在其中上下文的變化比較難理解,bind函數主要就是為了綁定上下文來使用的

 fToBind = this

 這里是保存了對象的上下文,緊接着下面的apply方法讓要被綁定的那個對象可以使用該上下文

 

 fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

 

這里是以fNOP為中介把this.prototype這個原對象的屬性給fBound,確保fBound是在定義的時候的那個上下文里面執行。本來

bound.prototype = self.prototype

就可以將原屬性集成過來了,但是這樣兩個對象屬性都指向同一個地方,修改 bound.prototype 將會造成self.prototype 也發生改變,這樣並不是我們的本意。所以通過一個空函數 nop 做中轉,能有效的防止這種情況的發生。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM