this
的工做原理JavaScript 有一套徹底不一樣於其它語言的對 this
的處理機制。
在五種不一樣的狀況下 ,this
指向的各不相同。數組
this;
當在所有範圍內使用 this
,它將會指向全局對象。瀏覽器
譯者注:瀏覽器中運行的 JavaScript 腳本,這個全局對象是
window
。閉包
foo();
這裏 this
也會指向全局對象。app
ES5 注意: 在嚴格模式下(strict mode),不存在全局變量。
這種狀況下this
將會是undefined
。函數
test.foo();
這個例子中,this
指向 test
對象。this
new foo();
若是函數傾向於和 new
關鍵詞一塊使用,則咱們稱這個函數是 構造函數。
在函數內部,this
指向新建立的對象。prototype
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
。code
注意: 在對象的字面聲明語法中,
this
不能用來指向對象自己。
所以var obj = {me: this}
中的me
不會指向obj
,由於this
只可能出如今上述的五種狀況中。
譯者注:這個例子中,若是是在瀏覽器中運行,obj.me
等於window
對象。對象
儘管大部分的狀況都說的過去,不過第一個規則(譯者注:這裏指的應該是第二個規則,也就是直接調用函數時,this
指向全局對象)
被認爲是JavaScript語言另外一個錯誤設計的地方,由於它歷來就沒有實際的用途。
Foo.method = function() { function test() { // this 將會被設置爲全局對象(譯者注:瀏覽器環境中也就是 window 對象) } test(); }
一個常見的誤解是 test
中的 this
將會指向 Foo
對象,實際上不是這樣子的。
爲了在 test
中獲取對 Foo
對象的引用,咱們須要在 method
函數內部建立一個局部變量指向 Foo
對象。
Foo.method = function() { var that = this; function test() { // 使用 that 來指向 Foo 對象 } test(); }
that
只是咱們隨意起的名字,不過這個名字被普遍的用來指向外部的 this
對象。
在 閉包 一節,咱們能夠看到 that
能夠做爲參數傳遞。
另外一個看起來奇怪的地方是函數別名,也就是將一個方法賦值給一個變量。
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
的實例對象。