全域範圍內
函數呼叫
方法呼叫
呼叫
方法的賦值表達式
JavaScript 有一套完全不同於其它語言的對 this 的處理機制。 在五種不同的情況下,this 指向的各不相同。
this;
當在全部範圍內使用 this ,它將會指向全域物件。
foo();
這裡 this 也會指向全域物件。
方法呼叫
test.foo();
這個範例中, this 指向 test 物件。
呼叫建構子
new foo();
如果函數傾向於和 new 關鍵字一塊使用,則我們稱這個函數為 建構子。 在函數內部,this 指向新建立的物件。
明確的設定 this
function foo(a, b, c) {} var bar = {}; foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,如下所示 foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3
當使用 Function.prototype 上的 call 或 apply 方法時,函數內的 this 將會被明確地設定為函數呼叫的第一個參數。
因此函數呼叫的規則在上例中已經不適用了,在 foo 函數內 this 被設定為bar了。
常見誤解儘管大部分的情況都說的過去,不過第一個規則(譯者註:這裡指的應該是第二個規則,也就是直接調用全局函數時,this 指向全局物件) 被認為是JavaScript語言另一個錯誤設計的地方,因為它從來就沒有實際的用途。
Foo.method = function() { function test() { // this 将会被设置为全局对象(译者注:浏览器环境中也就是 window 对象) } test(); }
一個常見的誤解是 test 中的 this 將會指向 Foo 對象,實際上不是這樣子的。
Foo.method = function() { var that = this; function test() { // 使用 that 来指向 Foo 对象 } test(); }
注意: 在物件的字面宣告語法中,this 不能用來指向物件本身。 因此 var obj = {me: this} 中的 me 不會指向obj,因為 this 只可能出現在上述的五種情況中。 譯者註:這個例子中,如果是在瀏覽器中執行,obj.me 等於window 物件。
方法的賦值表達式
另一個看起來奇怪的地方是函數別名,也就是將一個方法賦值給一個變數。
var test = someObject.methodTest; test();
上例中,test 就像一個普通的函數被呼叫;因此,函數內的 this 將不再被指向 someObject 物件。
雖然 this 的晚綁定特性似乎並不友好,但這確實是基於原型繼承賴以生存的土壤。
function Foo() {} Foo.prototype.method = function() {}; function Bar() {} Bar.prototype = Foo.prototype; new Bar().method();
當 method 被呼叫時,this 將會指向 Bar 的實例物件。
以上就是JavaScript進階系列—this 的工作原理的內容,更多相關內容請關注PHP中文網(www.php.cn)!