當一個函數被調用時,會建立一個活動記錄(執行上下文)。
這個記錄會包含函數在哪裡被調用(調用棧)、函數的調用方法、傳入的參數等資訊。
this就是記錄的其中一個屬性,會在函數執行的過程中用到。
this既不指向函數自身也不指向函數的作用域。
this實際上是在函數被調用時發生的綁定,它指向什麼完全取決于函數在哪裡被調用。
你必須找到調用位置,然後判斷需要應用下面四條規則中的哪一條。
1)預設綁定
最常用的函數調用類型:獨立函數調用。可以把這條規則看作是無法應用其他規則時的預設規則。
2)隐式綁定
隐式綁定的規則是調用位置是否有上下文對象,或者說是否被某個對象擁有或者包含。
但有時候會出現隐式丢失。
雖然bar是obj.foo的一個引用,但是實際上,它引用的是foo函數本身。
是以此時的bar()其實是一個不帶任何修飾的函數調用,應用了預設綁定。
3)顯式綁定
使用函數的call(..)和apply(..)方法。
在很多庫中經常能看到bind方法,這是一種硬綁定,一種顯式的強制綁定,下面是一種bind實作。
4)new綁定
使用new來調用函數,或者說發生構造函數調用時,會自動執行下面的操作:
1. 建立(或者說構造)一個全新的對象。
2. 這個新對象會被執行[[原型]]連接配接。
3. 這個新對象會綁定到函數調用的this。
4. 如果函數沒有傳回其他對象,那麼new表達式中的函數調用會自動傳回這個新對象。
預設綁定的優先級是四條規則中最低的。
1)顯式綁定優先級比隐式綁定要更高
2)new綁定比隐式綁定優先級高
3)new綁定會修改顯示綁定中this
4)判斷this
1. 函數是否在new中調用(new綁定)?如果是的話this綁定的是新建立的對象。
2. 函數是否通過call、apply(顯式綁定)或者硬綁定調用?如果是的話,this綁定的是指定的對象。
3. 函數是否在某個上下文對象中調用(隐式綁定)?如果是的話,this綁定的是那個上下文對象。
4. 如果都不是的話,使用預設綁定。如果在嚴格模式下,就綁定到undefined,否則綁定到全局對象。
1)被忽略的this
如果你把null或者undefined作為this的綁定對象傳入call、apply或者bind。
這些值在調用時會被忽略,實際應用的是預設綁定規則。
2)間接引用
你有可能(有意或者無意地)建立一個函數的“間接引用”。
在這種情況下,調用這個函數會應用預設綁定規則。
指派表達式p.foo = o.foo的傳回值是目标函數的引用,是以調用位置是foo()而不是p.foo()或者o.foo()。
3)軟綁定
如果可以給預設綁定指定一個全局對象和undefined以外的值。
那就可以實作和硬綁定相同的效果,同時保留隐式綁定或者顯式綁定修改this的能力。
可以通過一種被稱為軟綁定的方法來實作我們想要的效果。
軟綁定版本的foo()可以手動将this綁定到obj2或者obj3上。
但如果應用預設綁定,則會将this綁定到obj。
本文轉自 咖啡機(K.F.J) 部落格園部落格,原文連結:http://www.cnblogs.com/strick/p/5813749.html,如需轉載請自行聯系原作者