アロー関数のthisをやさしく理解する
アロー関数は「短く書ける関数」だけではありません。いちばんの特徴は、thisが「外側のthisに固定される(レキシカルに束縛される)」ことです。つまり、アロー関数の中でthisが何になるかは、宣言された場所のthisに依存し、呼び出し方で変わりません。
ふつうの関数とアロー関数の違い(核心)
- ふつうの関数: 呼び出し方で
thisが変わる(オブジェクトから呼べばそのオブジェクト、単独で呼べばundefinedやグローバル)。 - アロー関数: 宣言時の「外側のスコープの
this」に固定。call/apply/bindでも変えられません。
const obj = {
name: 'Alice',
// ふつうの関数(メソッド)
greet() {
console.log(this.name); // 'Alice'
},
// アロー関数
greetArrow: () => {
console.log(this.name); // ここでのthisは「外側」。多くの環境ではundefinedかグローバル
}
};
obj.greet(); // 'Alice'
obj.greetArrow(); // undefined(またはグローバルのname)
JavaScript- ポイント: オブジェクトのメソッドとしてアロー関数を使うと、期待どおりの
thisになりません。
どんなときに便利?(レキシカルthisの活躍)
クラスやオブジェクトの内部でコールバックに使う
「内部のthis(インスタンス)を保ちたい」場面で、アロー関数は強力です。
class Counter {
constructor() {
this.value = 0;
}
start() {
setInterval(() => {
// アロー関数なので、thisはCounterインスタンスのまま固定
this.value++;
console.log(this.value);
}, 1000);
}
}
const c = new Counter();
c.start();
// 1, 2, 3 ... と動く
JavaScript- ラベル: レキシカル固定
説明:setIntervalに渡した関数は後で呼ばれるが、thisが「外側のthis(Counterのインスタンス)」に固定される。
ネストした関数で外側のthisを使いたい
const timer = {
seconds: 0,
start() {
const tick = () => {
this.seconds++; // 外側(start内)のthisをそのまま使える
console.log(this.seconds);
};
setInterval(tick, 1000);
}
};
timer.start();
JavaScript- ラベル: 便利さ
説明: ふつうの関数で書くとthisが変わってしまうため、bind(this)が必要になる。アロー関数なら不要。
どんなときに使わないほうがいい?(落とし穴)
オブジェクトのメソッド定義
const user = {
name: 'Bob',
// NG例:メソッドをアローで定義
getName: () => this.name
};
console.log(user.getName()); // undefined
JavaScript- ラベル: 避ける理由
説明: アロー関数のthisは外側(グローバル)に固定されるため、userを指さない。メソッドは通常の関数記法で。
DOMイベントのハンドラで要素をthisにしたいとき
const btn = document.querySelector('#btn');
// NG:thisでボタンを参照したいならアローは不適
btn.addEventListener('click', () => {
console.log(this); // 外側のthis(windowなど)、ボタンではない
});
// OK:通常の関数ならthisがクリックされた要素に
btn.addEventListener('click', function() {
console.log(this); // <button id="btn">...</button>
});
JavaScript- ラベル: 使い分け
説明: 要素をthisで参照したいイベント処理は、通常の関数を使う。
call/apply/bindが効かない例
アロー関数のthisは固定されるので、後から変えられません。
const outer = { name: 'Outer' };
const arrow = () => {
console.log(this.name); // 外側のthis(たいていundefined)
};
const normal = function() {
console.log(this.name);
};
arrow.call({ name: 'A' }); // 変わらない → undefined
normal.call({ name: 'B' }); // 'B' に変えられる
JavaScript- ラベル: 不変性
説明:bindしてもアロー関数のthisは変わらない。設計時に「外側のthisを使う」と決まっているから。
実践的なパターン集
- クラスのプロパティとしてアロー(よく使う)
class Toggle {
constructor() { this.on = false; }
click = () => { this.on = !this.on; } // どこから呼んでもthisはインスタンス
}
const t = new Toggle();
const f = t.click;
f(); // 問題なくインスタンスを指す
JavaScript- 配列メソッドのコールバック(
map/filter)
const list = [1, 2, 3];
const doubled = list.map(n => n * 2);
JavaScriptラベル: 省コード
説明: thisに依存しない小さな関数は、アローで短く書くのが合う。
- 非同期で外側のthisを保つ
function Loader() {
this.done = false;
}
Loader.prototype.load = function() {
fetch('/data').then(() => {
// アローで外側のthis(Loaderインスタンス)を保持
this.done = true;
});
};
JavaScriptまとめ(使い分けの指針)
- 外側のthisを保ちたいとき: アロー関数が最適(タイマー、非同期、クラスのコールバック)。
- オブジェクトのメソッドやイベントで要素をthisにしたいとき: 通常の関数を使う。
call/apply/bindでthisを切り替えたい設計: 通常の関数を使う。- 短いコールバックでthisに依存しない処理: アロー関数で簡潔に。
「アローは外側のthisに固定」「メソッドやイベントでthisに期待があるなら通常の関数」——この2本柱を覚えておけば、迷いません。


