理解 JavaScript 中的 Function.prototype.bind

來源:互聯網
上載者:User

標籤:eof   rspec   運行   int   瀏覽器   firefox   代碼   function   上下文   

函數綁定(Function binding)很有可能是你在開始使用JavaScript時最少關注的一點,但是當你意識到你需要一個解決方案來解決如何在另一個函數中保持this內容相關的時候,你真正需要的其實就是 Function.prototype.bind(),只是你有可能仍然沒有意識到這點。

第一次遇到這個問題的時候,你可能傾向於將this設定到一個變數上,這樣你可以在改變了上下文之後繼續引用到它。很多人選擇使用 self, _this 或者 context 作為變數名稱(也有人使用 that)。這些方式都是有用的,當然也沒有什麼問題。但是其實有更好、更專用的方式。

我們真正需要解決的問題是什嗎?

在下面的例子代碼中,我們可以名正言順地將上下文緩衝到一個變數中:

 1 var myObj = { 2   3     specialFunction: function () { 4   5     }, 6   7     anotherSpecialFunction: function () { 8   9     },10  11     getAsyncData: function (cb) {12         cb();13     },14  15     render: function () {16         var that = this;17         this.getAsyncData(function () {18             that.specialFunction();19             that.anotherSpecialFunction();20         });21     }22 };23  24 myObj.render();

如果我們簡單地使用 this.specialFunction() 來調用方法的話,會發現程式有錯誤。

我們需要為回呼函數的執行保持對 myObj 物件內容的引用。 調用 that.specialFunction()讓我們能夠維持範圍上下文並且正確執行我們的函數。

然而使用 Function.prototype.bind() 可以有更加簡潔乾淨的方式:

 1 render: function () { 2   3     this.getAsyncData(function () { 4   5         this.specialFunction(); 6   7         this.anotherSpecialFunction(); 8   9     }.bind(this));10  11 }
我們剛才做了什嗎?

.bind()建立了一個函數,當這個函數在被調用的時候,它的 this 關鍵詞會被設定成被傳入的值(這裡指調用bind()時傳入的參數)。

因此,我們傳入想要的上下文,this(其實就是 myObj),到.bind()函數中。

然後,當回呼函數被執行的時候, this 便指向 myObj 對象。

瀏覽器支援
Browser Version support
Chrome 7
Firefox (Gecko) 4.0 (2)
Internet Explorer 9
Opera 11.60
Safari 5.1.4

正如你看到的,很不幸,Function.prototype.bind 在IE8及以下的版本中不被支援,所以如果你沒有一個備用方案的話,可能在運行時會出現問題。

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 () {          return fToBind.apply(this instanceof fNOP && oThis                                 ? this                                 : oThis,                               aArgs.concat(Array.prototype.slice.call(arguments)));        };     fNOP.prototype = this.prototype;    fBound.prototype = new fNOP();     return fBound;  };}

 

理解 JavaScript 中的 Function.prototype.bind

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.