關於 this
有許多大神有相當詳盡的解說,例如 Kuro 大的優質好文,不過身為一個初心者,先對 this
有個粗淺的認識再延伸閱讀,我想會比較適合。
關鍵字 this
經常使用在函式和物件之中,一般用來指向一個物件,通常是使用 this
的函式所隸屬的物件。因此,以下將依據函式所在位置的不同,來分別解釋 this
究竟是指向什麼物件。
當函式不隸屬任何自行定義的物件時,它就是處於全域範圍中,也就是說此時函式只隸屬於 window
物件。因此當 this
被寫在函式裡時,this
指的就是 window
物件。此現象稱為預設綁定 (Default Binding)。
function windowSize(){
var width = this.innerWidth;
var height = this.innerHeight;
return [height, width];
}
console.log(windowSize());
// innerWidth 跟 innerHeight 都是 window 物件內件的特性,代表視窗的高跟寬
由於所有全域範圍的變數都會變成 window
物件的特性,因此我們可以用 this
代表 window
物件來選取全域變數。
var width = 600;
var showWidth = function(){
console.log(this.width);
};
showWidth();
// 顯示結果為 600
當函式是建立在物件內,就成為物件中的一個方法,在方法之中的 this
指向的是它所在的物件。
var shape = {
width: 600,
height: 400,
getArea: function(){
return this.width * this.height;
}
};
console.log(shape.getArea());
// 顯示結果為 240000
如果函式宣告在全域範圍,但是被某個物件所參考,此時函式就成為該物件的參考屬性(reference property),那麼 this
指向的將會是該物件。這個現象稱為隱含式綁定(Implicit Binding)。
function func(){
console.log(this.width);
}
var shape = {
width: 300,
showWidth: func
};
func(); //undefined
shape.showWidth(); //300
如果一個物件中建立了一個方法,而該方法裡面又包了一個函式時,this
在外層的方法中會指向該物件,而 this
在內層的函式則仍是未指定的狀態,因此會指向 window
物件(依循預設綁定)。注意,如果是在嚴格模式之下,則內層函式的 this 不會指向 window
物件,而是 undefined
。
其實這個部分是從 Kuro 大的文章看來的(開頭提到的那篇),因為感覺是很容易犯的錯誤,所以就放進自己的筆記。
以下範例及說明均引用自 Kuro 大的文章:
var obj = {
func1: function(){
console.log( this === obj );
var func2 = function(){
// 這裡的 this 跟上層不同!
console.log( this === obj );
};
func2();
}
};
obj.func1();
在這個範例當中,會有兩次的 console。
在 obj.func1() 裡面的 console.log( this === obj ); 會印出 true,原因是因為 func1 是透過 obj 來呼叫的。
但 obj.func1() 裡面的 func2() 在執行時的 console.log( this === obj ); 卻會印出 false。
換言之,在 func2 裡頭的 this,若是沒有特別透過 call() 、 apply() 或是 bind() 來指定 this 的話,那麼這裡的 this 就是 window。
寫這篇文真的超心虛的,因為 this 的觀念沒有被收錄在六角的 JS 學徒試煉課程內,我是從另外買的書裡看到的(就前言提到的那本),而且篇幅還只有兩頁。但我手邊只有這個材料,也只能靠那兩頁寫筆記了......。
後來辜狗到了 Kuro 大的文,就發現,嗯,this 真是博大精深,我看完書之後還是只能看懂大概三分之二吧。所以我很推薦其他跟我一樣菜的同道可以在了解 this 基本觀念後,再去拜讀 Kuro 大的文當作延伸學習。
「Kuro 大的優質好文」連結無效
感謝,已經修好了~
你們是小精靈嗎?
回好快
ccutmis 大還比我先回應,太神了><
偷偷推薦一下自己的文章,希望能多少有點幫助:淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂
已拜讀!真的寫得深入淺出,讓我更加理解 this ~
不過看完以後發現有好多坑還沒補QQ(原型鍊、閉包等等)