iT邦幫忙

2021 iThome 鐵人賽

DAY 27
3
Modern Web

JavaScript 魔法入門 - 從入門到中階觀念系列 第 27

中階魔法 - this 指向(一)

前情提要

艾草:「this is a book。」

「你在做什麼呀?」

艾草:「練習你的語言呀。」
(艾草設定為鳥類。)

「很棒,繼續加油!」

艾草:「啊唸到 this ,想到還沒教你一個魔法的核心觀念!今天來學 this 吧!」


this 指向(一)

在執行環境與執行堆疊文章,有提到過創造階段 JavaScript 會去建立 this ,那 this 是什麼呢?

先複習一下:

  • 執行環境分為:全域執行環境、函式執行環境
  • 執行環境建立時分為:創造階段、執行階段
  • 執行環境創造階段會建立 this

接下來,把 this 印出來看看!

console.log(this);
function test() {
  console.log(this);
}
test();

印出結果:

https://ithelp.ithome.com.tw/upload/images/20211011/20139066bSKQ1ue988.png

會發現它們都指向 Window 物件,到這邊可能會以為 this 指向都固定都是指向全域執行環境建立的全域物件,接著看底下的例子:

let obj = {
    name: '艾草',
    mana: 1100,
    test: function () {
        console.log(this);
    }
};
obj.test();

印出結果:

https://ithelp.ithome.com.tw/upload/images/20211011/20139066istLaQLIf9.png

會發現它指向了 obj

這是為何呢?this 的指向跟它所處的執行環境無關,而跟如何呼叫它有關係,而範例程式碼的指向如圖:

https://ithelp.ithome.com.tw/upload/images/20211011/201390669HQMtFDWv2.png

請特別留意呼叫該函式時前方的物件為何,this 就會指向該物件。


接下來,來介紹幾種常見情境!

全域環境 this 指向

在全域環境下調用 this 的指向皆會指向全域物件。

console.log(this === window);//true

簡易呼叫 Simple Call

只要是簡易呼叫的方式,this 都會指向全域物件,簡易呼叫就是直接呼叫該函式,像上方一開始的範例:

var name = '全域艾草';
function sayHello() {
	let name = '艾草';
  console.log(`Hello , ${this.name}`);//Hello , 全域艾草
}
sayHello();

物件方法

物件方法內調用的函式會指向呼叫它的物件本身,也是上方範例有提到的部分,因為很重要,所以再來複習一次:

var name = '全域艾草';
let obj = {
    name: '艾草',
    sayHello: function () {
        console.log(`Hello , ${this.name}`);//Hello , 艾草
    }
};
obj.sayHello();

https://ithelp.ithome.com.tw/upload/images/20211011/20139066eGezRDTbbO.png

DOM 事件處理器

在監聽函式內調用 this 時,會發現 this 會指向觸發事件的元素本身:

HTML

<button type="button">按鈕</button>

JavaScript

let button = document.querySelector('button');
button.addEventListener('click', function (e) {
    console.log(this);
});

印出結果:

https://ithelp.ithome.com.tw/upload/images/20211011/20139066vlFa3ADzXQ.png

總結

  • 全域環境下調用 this 會指向全域物件
  • 簡易呼叫下調用的 this 會指向全域物件
  • 物件方法調用的 this 會指向調用它的物件
  • 監聽函式內調用的 this 會指向觸發事件的元素

小練習

請問以下 this 的指向敘述何者錯誤?

//選項一
//全域情況下
console.log(this);

//選項二
let num = 1;
let obj = {
  num: 2,
  add: function () {
    console.log(this.num + this.num);
  }
};
obj.add();

//選項三
var num = 1;
function add() {
  let num = 2;
  console.log(this.num + this.num);
}
add();

A 選項一會指向全域物件 Window
B 選項二會印出 4
C 選項三會印出 4

解答: C 錯誤,選項三印出結果為 2 ,選項三為簡易呼叫,簡易呼叫下 this 會指向全域


參考文獻

JavaScript 全攻略:克服 JS 的奇怪部分(Udemy)
Vue 3 實戰影音課程(六角學院)
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/this


上一篇
中階魔法 - 閉包 Closure (二)
下一篇
中階魔法 - this 指向(二)
系列文
JavaScript 魔法入門 - 從入門到中階觀念30

1 則留言

我要留言

立即登入留言