this 是 JavaScript 中的一個關鍵字,它的值通常根據呼叫方式決定。箭頭函式例外,它在定義時就繼承外層的 this。
| 呼叫方式/情境 | this 指向(在瀏覽器中) | 備註 | 
|---|---|---|
| 全域(非嚴格模式) | window | Node.js 中為 global | 
| 全域(嚴格模式) | undefined | |
| 函式直接呼叫 | window(非嚴格) /undefined(嚴格) | |
| 物件方法呼叫 | 呼叫該方法的物件 | 例如 obj.method() | 
| constructor 中 ( new) | 新建立的實體物件 | this指向new出來的物件 | 
| class 中的 method | 該 class 實體 | 類似一般物件的行為 | 
| callback 函式(一般函式) | window(非嚴格) /undefined(嚴格) | 例如: [1,2,3].forEach(function(){}) | 
| setTimeout/setInterval | window | Node.js 中為 Timeout(但非預期) | 
| IIFE(立即執行函式) | window(非嚴格) /undefined(嚴格) | 
箭頭函式永遠不會自己創造 this,它只會繼承「定義當下」的外層 this
this 行為總表| 定義位置 / 外層 this | 箭頭函式的 this指向(在瀏覽器中) | 備註 | 
|---|---|---|
| 全域 | window | 若在全域中定義箭頭函式 | 
| class 中的 method | 該 class 實體 | this繼承外層 class context,例如 constructor 中定義箭頭函式 | 
| setTimeout / setInterval 中定義 | 外層 this | 例如在物件內使用箭頭函式當定時器 callback,會指向物件本身 | 
| callback 函式 | 外層 this | 常見於 class 或物件中使用 forEach 來處理資料時 | 
| IIFE(立即執行函式) | 外層 this | 箭頭函式沒有自己的作用域,直接吃外面那層 | 
🧠 箭頭函式的 this 核心原則:
箭頭函式永遠不會自己創造this,它只會繼承「定義當下」的外層this。
var myName = "小明";
console.log(this === window); // true(在瀏覽器中)
console.log(this.myName);     // "小明"
"use strict";
var myName = "小明";
function fn() {
  console.log(this); // undefined
}
fn();
var myName = "小明";
function sayName() {
  console.log(this);        // window(非嚴格)
  console.log(this.myName); // "小明"
}
sayName();
var myName = "小明";
(function () {
  console.log(this); // window(非嚴格)
})();
(() => {
  console.log(this); // window,箭頭函式繼承外層的 this
})();
const family = {
  myName: "小明家",
  callName() {
    console.log(this.myName); // "小明家"
  },
};
family.callName();
const family = {
  myName: "小明家",
  ming: {
    myName: "小明",
    callName() {
      console.log(this.myName); // "小明"
    },
  },
};
family.ming.callName();
class Person {
  constructor(name) {
    this.name = name; 
    console.log(this);// this 指向 new 出來的物件
  }
  sayHi() {
    console.log("Hi, I am", this.name); // this 指向呼叫 sayHi() 的實例物件
  }
}
const p1 = new Person("小明");
p1.sayHi(); // this === p1 → "Hi, I am 小明"
[1, 2, 3].forEach(function () {
  console.log(this); // window(非嚴格)
});
"use strict";
const arr = [1, 2, 3];
arr.forEach(function (item) {
  console.log(this); // ❗️在嚴格模式下,這裡的 this 是 undefined
});
🔹 普通函式寫法(需要保存 this)
const component = {
  text: "Hello",
  getData() {
    const that = this;
    setTimeout(function () {
      that.text = "Hi";
      console.log(that.text); // "Hi"
    });
  },
};
component.getData();
🔹 箭頭函式寫法(自動繼承外層 this)
const person = {
  name: "小明",
  sayHi() {
    setTimeout(() => {
      console.log(this.name); // "小明"
    }, 1000);
  },
};
person.sayHi();
window.myName = "全域的小明";
const family = {
  myName: "小明家",
  callName: () => {
    console.log(this.myName); // "全域的小明"(繼承外層的 this = window)
  },
};
family.callName();
window.myName = "全域的小明";
const family = {
  myName: "小明家",
  callName: function () {
    (() => {
      console.log(this.myName); // "小明家"
    })();
  },
};
family.callName();
const component = {
  text: "預設文字",
  el: document.getElementById("root"),
  getData() {
    const that = this;
    setTimeout(function () {
      that.text = "已更新";
      that.render();
    });
  },
  init() {
    this.getData();
  },
  render() {
    this.el.innerText = this.text;
  },
};
const component2 = {
  ...component,
  el: document.getElementById("root2"),
};
component.init();
component2.init();