iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
1
Modern Web

JavaScript 初心者筆記系列 第 11

JavaScript 初心者筆記: this 關鍵字

關於 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 在外層的方法中會指向該物件,而 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 大的文當作延伸學習。


上一篇
JavaScript 初心者筆記: JS 內建物件 - 全域物件篇
下一篇
JavaScript 初心者筆記: 判斷式 - 運算子篇
系列文
JavaScript 初心者筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
來杯拿鐵
iT邦新手 2 級 ‧ 2019-09-12 10:57:17

「Kuro 大的優質好文」連結無效

看更多先前的回應...收起先前的回應...
ccutmis iT邦高手 2 級 ‧ 2019-09-12 10:59:37 檢舉
Grete Ma iT邦新手 5 級 ‧ 2019-09-12 11:00:25 檢舉

感謝,已經修好了~

你們是小精靈嗎?
回好快

Grete Ma iT邦新手 5 級 ‧ 2019-09-12 11:07:22 檢舉

ccutmis 大還比我先回應,太神了><

1
huli
iT邦新手 3 級 ‧ 2019-09-12 15:44:36

偷偷推薦一下自己的文章,希望能多少有點幫助:淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂

Grete Ma iT邦新手 5 級 ‧ 2019-09-12 21:57:56 檢舉

已拜讀!真的寫得深入淺出,讓我更加理解 this ~
不過看完以後發現有好多坑還沒補QQ(原型鍊、閉包等等)

我要留言

立即登入留言