# [JavaScript] this ###### tags: `JavaScript` ## 關於 this * JavaScript 的一個關鍵字 * function 執行時,自動生成的一個內部物件 * 隨著 function 執行場合的不同,this 所指向的值也會有所不同 * 決定 this 的關鍵在於 function「呼叫的時機點」,當透過物件呼叫某個方法的時候,此時 this 就是那個物件 * 代表的是 function 執行時所屬的物件,而不是 function 本身 * 在大多數的情況下,this 代表的就是呼叫 function 的物件 ## 綁定的基本原則 ### 1. 預設綁定(Default Binding) * function 被呼叫的當下如果沒有值或透過顯式綁定時指定的的物件為空、`null`、`undefined`,**此時 this 為全域物件**,也就是 window * 在嚴格模式 `'use strict';` 下,會禁止 this 自動指定為全域物件,**此時 this 為 `undefined`** ```javascript function fn() { console.log(this); } // 以下幾種寫法的 this 都是 Window { ... } fn(); fn.call(); fn.call(null); fn.call(undefined); // .call() 改成 .bind() 或 .apply() 的寫法也是相同的結果 ``` ### 2. 隱含式綁定(Implicit Binding) * 即使 function 被宣告的地方是在 global scope 中,只要它成為某個物件的參考屬性(存在於某個物件內),在被呼叫的當下,該 function 即被那個物件所包含,**此時 this 為那個物件** ```javascript function fn() { console.log(this.num); } const obj = { num: 10, func: fn }; fn(); // undefined obj.func(); // 10 ``` ### 3. 顯式綁定(Explicit Binding) * 透過 `.bind()`、`.call()`、`.apply()` 指定、呼叫時,**此時 this 為被指定的物件** ### 4. `new` 關鍵字綁定 * 透過 `new` 呼叫 function 時,會產生一個新的物件,並設為 this 的綁定目標,**此時 this 為新建構的物件** * 若 function return 其他物件,**此時 this 為 return 的物件** ```javascript! const foo = { a: 'obj' }; function C1() { this.a = 37; } function C2() { this.a = 37; return { a: 38 }; } function C3() { this.a = 37; return foo; } const obj1 = new C1(); const obj2 = new C2(); const obj3 = new C3(); console.log(obj1.a); // 37 console.log(obj2.a); // 38 console.log(obj3.a); // 'obj' ``` ## 箭頭函式的 this * 沒有自己的 this * 在定義時 this 的指向就已經固定,不會變更 ```javascript const obj1 = { name: 'obj1 name' }; function fn() { console.log('fn: ', this); setTimeout(function () { console.log('setTimeout: ', this); }, 1000); setTimeout(() => { console.log('setTimeout arrow function: ', this); }, 1000); } fn.bind(obj1)(); // fn: {name: 'obj1 name'} // setTimeout: Window { ... } // setTimeout arrow function: {name: 'obj1 name'} ``` ```javascript const obj2 = { i: 10, b: () => console.log(this.i, this), c() { console.log(this.i, this); }, }; obj2.b(); // undefined Window { ... } obj2.c(); // 10 {i: 10, b: ƒ, c: ƒ} ``` ## 參考資料 * [0 陷阱!0 誤解!8 天重新認識 JavaScript! | 作者: 許國政 (Kuro)](https://www.drmaster.com.tw/bookinfo.asp?BookID=MP21913) * [this - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) * [Arrow function expressions - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#cannot_be_used_as_methods) --- :::info 建立日期:2024-02-12 更新日期:2024-02-12 :::