0%

JavaScript 核心 (34) - 函式以及 This 的運作 - 最常見的 this:物件的方法調用

this

先來介紹 this 是什麼?出現在什麼時候?

1
2
3
function fn() {}

fn();

執行上述範例後,可在 F12 source 中得知 this 會指向 Window
因此,只要執行環境成立,this 就會自動生成,不需要額外設定。
只是要知道這個 this 到底是指向什麼東西。

this 基本觀念

以下三點是 this 觀念

  • 每個執行環境都有屬於自己的 this 關鍵字
  • this 與函式如何宣告沒有關連性,僅與 呼叫方法 有關
  • 嚴格模式下,簡易呼叫會有很大的改變
    this 觀念

影響 this 的呼叫方法

  • 作為物件方法(最常運用 this 的方法)
  • 簡易呼叫(絕大多數的呼叫方式)
  • bind、apply、call 方法
  • new
  • DOM 事件處理器
  • 箭頭函式(ES6)
    影響 this 的呼叫方法

切記,看到 this 不要慌,找出這個 this 是依照上述哪一個方法呼叫的,就能知道這個 this 到底是指向誰?

this 作為物件方法調用(最常見形式)

  • 物件方法調用時,僅須關注是在哪一個物件下呼叫的
1
2
3
4
5
6
7
8
var data = {
name: 'Cloud',
callName() {
console.log(this.name);
},
}

data.callName(); /* Cloud */

由於 callName() 是在 data 底下呼叫的,所以 callName 中的 this 就會指向 data 這個物件。

一般不會將函式寫在物件內,而是獨立出來在用變數賦予物件內的屬性使用:

1
2
3
4
5
6
7
8
9
function fn () {
console.log(this.name);
}
var data = {
name: 'Cloud',
callName: fn,
}

data.callName(); /* Cloud */

我們不需要管 fn() 在哪裡, 只需要知道 fn() 是怎麼呼叫的,上述範例依舊是回傳 Cloud

在複雜一點的範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fn () {
console.log(this.name);
}
var data = {
name: 'Cloud',
callName: fn,
ming: {
name: 'Cloud2',
callName: fn,
}
}

data.callName(); /* Cloud */
data.ming.callName(); /* Cloud2 */

data.callName() 是在 data 底下呼叫,指向 data
data.ming.callName() 則是在 data.ming 底下呼叫,指向 data.ming

來看看以下錯誤示範:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function fn () {
console.log(this.myName);
}
var data = {
myName: 'Cloud',
callName: fn,
ming: {
myName: 'Cloud2',
callName: fn,
}
}

var a = data.callName;
a(); /* undefined */
/* window.a(); */

為什麼是 undefined 呢?
this.myName 是由 a() 呼叫,而 a() 也等於 window.a(),所以這個 this 會指向 window,並且因為 window.myName 沒有值,所以是 undefined。

那該如何修正呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var myName = 'Cloud3'
function fn () {
console.log(this.myName);
}
var data = {
myName: 'Cloud',
callName: fn,
ming: {
myName: 'Cloud2',
callName: fn,
}
}

var a = data.callName;
a(); /* Cloud3 */

只要在全域賦予一個變數 myName 即可。

參考資料

六角學院 - JavaScript 核心篇
JavaScript 核心觀念(40)-函式以及 This 的運作-最常見的 this:物件的方法調用