標籤:
關鍵字 this 綁定的方法
this的動態切換,固然為JavaScript創造了巨大的靈活性,但也使得編程變得困難和模糊。有時,需要把this固定下來,避免出現意想不到的情況。JavaScript提供了call、apply、bind這三個方法,來切換/固定this的指向。
1. apply(thisArg[,args])
call(thisArgs [,args...]) 後面跟的是若干個參數列表 而 apply接收的是參數數組。
thisArgs指定了函數在運行期的調用者,也就是函數中的this對象,而參數列表會被傳入調用函數中。thisArgs的取值有以下4種情況:
A): 不傳,或者傳null,undefined, 函數中的this指向window對象
B): 傳遞另一個函數的函數名,函數中的this指向這個函數的引用
C): 傳遞字串、數值或布爾類型等基礎類型,函數中的this指向其對應的封裝對象,如 String、Number、Boolean
D): 傳遞一個對象,函數中的this指向這個對象
這是call的核心功能,它允許你在一個對象上調用該對象沒有定義的方法,並且這個方法可以訪問該對象中的屬性。
3. apply
apply(thisArgs[,args[]])
apply和call的唯一區別是第二個參數的傳遞方式不同,apply的第二個參數必須是一個數組,而call允許傳遞一個參數列表。值得你注意的是,雖然apply接收的是一個參數數組,但在傳遞給調用函數時,卻是以參數列表的形式傳遞。
function b(x,y,z){
console.log(x,y,z);
}
b.apply(null,[1,2,3]); // 1,2,3
4. bind
bind(thisArgs [,args...])
bind是ES5新增的一個方法,它的傳參和call類似,但又和call/apply有著顯著的不同,即調用call或apply都會自動執行對應的函數,而bind不會執行對應的函數,只是返回了對函數的引用。其實,ES5引入bind的真正目的是為了彌補call/apply的不足,由於call/apply會對目標函數自動執行,從而導致它無法在事件綁定函數中使用,因為事件綁定函數不需要我們手動執行,它是在事件被觸發時由JS內部自動執行的。而bind在實現改變函數this的同時又不會自動執行目標函數,因此可以完美的解決上述問題
當點擊網頁時,onClick被觸發執行,輸出onepixel p1 p2, 說明onClick中的this被bind改變成了obj對象,為了對bind進行深入的理解,我們來看一下bind的polyfill實現。
5. 應用情境
繼承:因為JavaScript 沒有類繼承 也不能像java c# 一樣。所有 我們可以使用call apply實現繼承。
6. Function.prototype.bind
我們真正需要解決的是什麼?
Function.prototype.bind() 是不支援IE8 以及以下的瀏覽器的。可以在MDN有一個很棒的資源。
適用的模式
click handlers(點擊處理函數) 點擊之後響應或記錄事件。
setTimeout 可以實現此功能。
JavaScript 之 call apply bind