導言
在這篇文章中我們將討論一個與執行上下文直接相關各更多細節。討論的主題就是this關鍵字。
實踐表明,這個主題很難,在不同執行上下文中this值的確定經常導致問題。
許多程序員習慣的認為,在程序語言中,this關鍵字與面向對象的程序緊密相關,完全指向通過構造器創建的新的對象。在ECMAScript中也是這樣執行的,但正如你看到的那樣,這并不限于創建對象的定義。
讓我們更詳細的了解ECMAScript中真正的this值是什么?
定義
這個值是執行上下文中的一個屬性。
activeExecutionContext = { VO: {...}, this: thisValue};
這里VO使我們前面討論的變量對象。
this與上下文中可執行代碼密切直接相關,這個值取決于進入的上下文,代碼在上下文中運行時一成不變
全局代碼中的this值
在這里一切都簡單。在全局代碼中,this始終是全局對象本身,這樣有可能間接的引用它。
// explicit property definition of// the global objectthis.a = 10; // global.a = 10alert(a); // 10// implicit definition via assigning// to unqualified identifierb = 20;alert(this.b); // 20// also implicit via variable declaration// because variable object of the global context// is the global object itselfvar c = 30;alert(this.c); // 30
函數代碼中的this值
在函數代碼中使用this 時很有趣,這種情況很難且會導致很多問題。
這種類型的代碼中,this值的首要特點(或許是最主要的)是它不是靜態的綁定到一個函數。
正如我們上面曾提到的那樣,這個值取決于進入的上下文,在一個函數代碼中,這個值在每一次完全不同。
但是,在代碼運行時的this值是不變的,也就是說,既然它不是一個變量,就不可能為其分配一個新值(相反,在Python編程語言中,它明確的定義為對象本身,在運行期間可以不斷改變)。
var foo = {x: 10};var bar = { x: 20, test: function () { alert(this === bar); // true alert(this.x); // 20 this = foo; // error alert(this.x); // if there wasn't an error then 20, not 10 }};// on entering the context this value is// determined as "bar" object; why so - will// be discussed below in detailbar.test(); // true, 20foo.test = bar.test;// however here this value will now refer// to "foo" – even though we're calling the same functionfoo.test(); // false, 10