概要
JavaScriptの this
は “関数がどこで定義されたか”ではなく、“どう呼び出されたか”に依存して決まる。
これは柔軟性を提供する反面、開発者の混乱とバグの温床になりやすい。
本稿では以下を徹底整理する:
-
this
の文脈による挙動パターン - アロー関数による束縛とその限界
-
bind
,call
,apply
の使い分け - クラス内メソッドとthisの一貫性
-
this
を意図通りに設計するための実用的戦略
1. グローバル文脈での this
console.log(this); // ブラウザ → window / Node.js → global
- 関数呼び出しではグローバルに束縛される(非strictモード)
-
strict mode
ではthis === undefined
'use strict';
function f() {
console.log(this); // undefined
}
2. メソッド呼び出しと this
const obj = {
name: 'Toto',
say() {
console.log(this.name);
}
};
obj.say(); // 'Toto'
→ ✅ this
は obj
を参照(呼び出し元がobj)
3. 代入やコールバックでthisが失われるケース
const fn = obj.say;
fn(); // ❌ undefined(グローバルthis)
→ ✅ this
を失う → bind
で固定する必要がある
4. bind
, call
, apply
による明示的バインディング
const bound = obj.say.bind(obj);
bound(); // ✅ 'Toto'
obj.say.call({ name: 'Alice' }); // 'Alice'
obj.say.apply({ name: 'Bob' }); // 'Bob'
メソッド | 意味 | 引数の渡し方 |
---|---|---|
bind |
this を束縛して関数を返す |
事前定義 |
call | その場で実行、this指定 | func.call(this, a, b) |
apply | その場で実行、this指定 | func.apply(this, [a, b]) |
5. アロー関数における this の束縛
const obj = {
name: 'Toto',
say: () => {
console.log(this.name); // ❌ undefined
}
};
obj.say(); // ❌ 'this'はobjではなくグローバルを参照
- ✅ アロー関数は
this
を“レキシカルに束縛”する - ✅ 親スコープの
this
を引き継ぐ - ❌ オブジェクトメソッドでは非推奨
6. クラスにおける this とbindの必要性
class Button {
constructor(label) {
this.label = label;
this.handleClick = this.handleClick.bind(this); // ✅
}
handleClick() {
console.log(`${this.label} clicked`);
}
}
→ ✅ イベントリスナーなど、外部で呼び出される関数にはbindが必須
7. よくあるthisのバグと防御策
❌ イベントハンドラで this がずれる
element.addEventListener('click', obj.say); // ❌ this is not obj
→ ✅ obj.say.bind(obj)
を渡す
❌ setTimeout や Promiseチェーンで this を失う
setTimeout(obj.say, 1000); // ❌
setTimeout(() => obj.say(), 1000); // ✅ アロー関数で文脈保持
設計判断フロー
① this を“呼び出し元に依存させたい”? → 通常の function
② this を“常に固定”したい? → bind を使う
③ this を“親スコープに追従”させたい? → アロー関数
④ コールバック・イベントで this を使う? → bind か ラップ関数で固定
⑤ クラスメソッドを外部に渡す? → constructorでbind
結語
this
は単なる参照ではない。
それは 関数が“どこで”ではなく、“どう”呼ばれたかに意味を持たせる構文的文脈である。
- アロー関数は束縛のための簡潔な文法
- bind/call/applyは明示的な意思の表現
-
this
の誤用は“意図のズレ”から始まる
thisを制御するとは、関数の責務と文脈を設計することである。