Open1
【久々に触れると忘れる/備忘録】定義方法と呼び出し方で変化するthis(TypeScript)
JavaScript / TypeScript の this は、「定義方法」と「呼び出し方」の2軸で参照先が変化します。
ざっくりとでも思い出せるよう、備忘録としてまとめました。
| 軸 | 意味 |
|---|---|
| ① 定義方法 | 通常関数 or アロー関数 |
| ② 呼び出し方 | 直接呼び出し or ドット演算子呼び出し |
1. 通常関数定義:直接呼び出し/ドット演算子による呼び出し
function で定義した関数は、呼び出し方によって this が動的に決まるという特徴があります。
- オブジェクト経由で呼び出す → そのオブジェクトが this
- 直接呼び出す → strictモードなら undefined、非strictモードなら window
function greet() {
console.log(this); // A: userオブジェクト / B: undefined
console.log(this.name); // A: "Tasuke" / B: TypeError
}
const user = {
name: "Tasuke",
greet,
};
user.greet();
// ドット演算子で呼び出したため this は user
greet("B");
// オブジェクトを経由しない直接呼び出し。
// strict:true → this = undefined(TypeError)
// strict:false → this = window
💡 ポイント
通常関数は「呼び出し時」に this が動的に決定される。
そのため、どこから呼び出すかによって結果が変化する。
2. オブジェクト内関数内アロー関数:ドット演算子による呼び出し
次は、関数の中でアロー関数を使うケースです。
アロー関数は 自分の this を持たず、外側の this を引き継ぐ 特性があります。
const obj1 = {
name: "Yuki",
start() {
console.log(this); // obj1
console.log(this.name); // "Yuki"
const fn = () => console.log(this.name);
fn(); // アロー関数は外側(start)の this = obj1 を引き継ぐ
},
};
obj1.start();
💡 ポイント
アロー関数は「定義時の this」を固定(動的ではない)。
この例では、外側の start() の this が obj1 のため、内部のアロー関数も obj1 を参照。
3. オブジェクト内関数 + アロー関数:ドット演算子による呼び出し
最後は、同じオブジェクト内で function とアロー関数を比較してみましょう。
両者の違いが最も明確に現れます。
const obj2 = {
name: "Rika",
show1: function() {
console.log(this); // obj2
console.log(this.name); // "Rika"
},
show2: () => {
console.log(this); // window
// アロー関数は this を持たないため、
// 定義時スコープ(ブラウザでは window)を参照。
console.log(this.name);
// window.name(初期値は空文字)を参照するため、TypeError にはならない。
},
};
obj2.show1();
obj2.show2(); // show2 はアロー関数のため、this は obj2 ではなく window を参照。
💡 ポイント
通常関数 → 呼び出し元オブジェクトにバインドされる
アロー関数 → 定義時スコープに固定される(ブラウザでは window)
まとめ:this のルール一覧
| 定義方法 | 呼び出し方 | this の参照先 |
|---|---|---|
| 通常関数 | ドット演算子 | 呼び出し元オブジェクト |
| 通常関数 | 直接呼び出し |
undefined(Strict) / window(非Strict) |
| アロー関数 | すべての呼び出し方 | 定義時スコープ(外側の this を参照) |
| 関数内アロー関数 | ドット演算子 | 外側関数の this を引き継ぐ |
覚え方
| 種類 | this の決定タイミング | 性質 |
|---|---|---|
| function | 呼び出し時に決まる | 🔄 動的(呼び出し元に依存) |
| アロー関数 | 定義時に決まる | 🧭 静的(外側スコープを固定) |