# [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
:::