---
# System prepended metadata

title: JS 核心觀念筆記 - 什麼是 this

---

# JS 核心觀念筆記 - 什麼是 this

![this](https://images.unsplash.com/photo-1507652955-f3dcef5a3be5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80)
```javascript
var vm = '全域';

function callName() {

}
callName();
```

上方有一個全域變數與函式，函式內沒有任何東西，當呼叫此函式時，執行堆疊會看到作用域中產生 this 並指向 window。

![this](https://i.imgur.com/J8TanZu.png)

而這個 this 的指向與如何呼叫此函式的方式有很大的關連性。

修改函式內容：

```javascript
var vm = '全域';

function callName() {
console.log(this.vm); //全域
}
callName();
```
此時函式中執行的 console 中是指向全域的變數，所以得到的是 vm 的值，由此可知函式中會自動升成 this。

## this 的基本觀念

* 不管是全域或是特定函式，都可以直接調用 this 這個關鍵字，而 this 會在每個執行環境都會存在，所以會容易被誤會為指向該函式本身。但函式能提供的方法很有限，故比較不會使用 this 調用函式本身，this 比較常被拿來指向該物件，但因為函式本身也是物件，所以這是造成誤解的原因。
* 每個環境都有自己的 this 關鍵字。
* this 與函式如何宣告**沒有關連性**，僅與呼叫方式有關。
* **嚴格模式下**，簡易呼叫會有很大的改變。

### 影響函式 this 的調用方式

* 做為物件方法(最常使用)。
* 簡易呼叫(絕大多數的呼叫方式，要避免使用此呼叫方式來調用 this)。
* bind,apply,call 將 this 綁定的特定方法。
* new 一個物件(建構式的運算子)。
* DOM 事件處理器。
* 箭頭函式(ES6)。

### this 的用途

* 可略過函式的定義方式，改依據執行的方式取用特定物件。

## this 物件方法的調用(最常使用)

* this 與函式如何宣告**沒有關連性**，僅與呼叫方法有關。
* 物件的方法調用時，僅需要關注的是**哪一個物件下**呼叫。

![thisObj](https://i.imgur.com/Bw2oUbs.png)

> 示意圖如上，掌握此概念就能使用大部份的 this。

### 範例一
```javascript
var vm = '全域';

function callName() {
  console.log(this.vm);
}

var ming = {
  vm: "區域",
  callName: callName
}

ming.callName(); //區域
```
上方有兩個物件，一個是函式，一個是物件，執行是由 ming 這個物件來呼叫函式，所以得到的 vm 直為區域變數的值。

### 範例二
若今天在函式中還有一個函式，如前面所說，不需要管函式怎麼定義，只要知道是哪個物件呼叫 this，第一個函式呼叫的結果就會是區域，第二個函式呼叫後是在 name 被呼叫，所以所得的值會是 name 裡面的 vm。
```javascript
var vm = '全域';

function callName() {
  console.log(this.vm);
}

var ming = {
  vm: "區域",
  callName: callName,
  name: {
    vm: "區域中的區域",
    callName: callName
  }
}

ming.callName(); //區域
ming.name.callName(); //區域中的區域
```
### 範例三
今天在物件中宣告一個函式，並且宣告一個變數來存取物件中函式的值，但因為函式宣告前面並沒有使用物件，所以 this 會指向全域(window)，所以得出來的值會是最外層全域的 vm 的值。
```javascript
var vm = '全域';

var ming = {
  vm: "區域",
  callName: function () {
    console.log(this.vm);
  }
}
var callName = ming.callName;
callName(); //全域
```



## 資料參考

1.  [鐵人賽：JavaScript 的 this 到底是誰？](https://wcc723.github.io/javascript/2017/12/12/javascript-this/)
2.  [JavaScript This 系列文：this 為什麼指向 window](https://wcc723.github.io/javascript/2019/03/21/this-why-window/)
4.  [JavaScript This 系列文：this 與物件的關係](https://wcc723.github.io/javascript/2019/03/18/JS-THIS/)
5.  [重新認識 JavaScript: Day 20 What's "THIS" in JavaScript (鐵人精華版)](https://ithelp.ithome.com.tw/articles/10193193)