this とは何か
JavaScript の this は、「今そのコードを実行している“受け手(コンテキスト)”を指す特別なキーワード」です。関数の中で this を参照すると、「誰がその関数を呼んだのか」「どんな形で呼ばれたのか」によって値が変わります。重要なのは、this は「どこで定義したか」ではなく「どう呼んだか」で決まるという点です(ただしアロー関数を除く)。
基本ルールの全体像(重要ポイントを深掘り)
this の値は、呼び出し方のパターンでほぼ決まります。直感をつかむには「呼び出し元とのつながり」を見るのがコツです。
グローバルでの this
console.log(this); // ブラウザなら window、Node.js のモジュール内トップでは {}(厳密には異なる)
JavaScriptトップレベルの this は環境によって異なります。ブラウザではほぼ window を指し、Node.js のモジュールではトップで this はモジュールスコープのオブジェクトになります。
通常の関数呼び出し
function f() {
console.log(this);
}
f(); // 非 strict: グローバル(ブラウザなら window) / strict: undefined
JavaScript「ただの関数」として呼ぶと、this はグローバルか undefined になります。ここが重要です:"use strict"(厳格モード)では暗黙のグローバル束縛がなくなり、this は undefined になります。
メソッド呼び出し(オブジェクト.メソッド)
const obj = {
value: 42,
show() {
console.log(this.value);
}
};
obj.show(); // 42(this は obj)
JavaScript「オブジェクトのプロパティとしての関数」を「ドットで呼ぶ」場合、this はそのオブジェクトになります。重要:代入や参照方法を変えると this が外れることがあります(後述)。
コンストラクタ呼び出し(new)
function User(name) {
this.name = name; // new によって「新しいインスタンス」が this
}
const u = new User("太郎");
console.log(u.name); // 太郎
JavaScriptnew を付けて呼ぶと、this は新しく作られたインスタンスを指します。
呼び出し形の違いで起きる“はまりどころ”(深掘り)
呼び出し時の“受け手”が変わると this が変わります。特に「メソッドを取り外す」ケースは初心者がつまずきがちです。
メソッドを変数に取り出すと this が失われる
const obj = {
value: 100,
show() { console.log(this.value); }
};
const fn = obj.show;
fn(); // 非 strict: undefined を参照しようとしてエラー、strict: this が undefined
JavaScriptobj.show をそのまま変数に入れて「ただの関数」として呼ぶと、this はオブジェクトを指しません。重要:関数本体は「どこで定義したか」ではなく「どう呼ばれたか」で this が決まるため、オブジェクトから切り離すと this が消えます。
call / apply / bind で this を明示的に固定する
function show() { console.log(this.msg); }
const ctx = { msg: "固定した this" };
show.call(ctx); // 固定した this
show.apply(ctx); // 固定した this
const bound = show.bind(ctx);
bound(); // 固定した this(常に ctx)
JavaScript- call/apply は「今だけ this をこれにして呼ぶ」。
- bind は「いつ呼んでも this を固定する関数を返す」。
「取り外したメソッドを安全に使いたい」場合は bind が便利です。
アロー関数と通常の関数の this の違い(重要ポイントを深掘り)
アロー関数は「自分専用の this を持たず、外側の this を“そのまま”使う」性質があります(レキシカル this)。これが通常の関数との決定的な違いです。
アロー関数は外側の this を捕まえる
const obj = {
value: 7,
showLater() {
setTimeout(() => {
console.log(this.value); // アロー関数は showLater の this(obj)を使う
}, 0);
}
};
obj.showLater(); // 7
JavaScript通常の関数で書くと setTimeout の中は「ただの関数呼び出し」になるため、this が外れることがあります。アロー関数なら外側の this にレキシカルに束縛され、期待通りに動きます。
しかし、アロー関数を「メソッド自体」に使うのは非推奨
const obj = {
value: 7,
show: () => { console.log(this.value); }
};
obj.show(); // 期待通りに動かない(this は obj にならない)
JavaScriptアロー関数の this は「定義した場所の外側 this」。オブジェクトリテラルのトップで定義すると、期待する「obj」を指しません。メソッド本体は通常の関数記法で定義し、内部のコールバックにはアロー関数を使う、が定石です。
イベントハンドラと this の直感
ブラウザのイベントでは、昔ながらの DOM API では this が「イベント発生元」を指すことがありますが、近年はアロー関数や event.currentTarget を使うことが増えています。
button.addEventListener("click", function (e) {
console.log(this === e.currentTarget); // true(function の this はイベントの受け手に結びつく)
});
button.addEventListener("click", (e) => {
console.log(this === e.currentTarget); // false(アロー関数は外側の this)
});
JavaScriptイベントの「受け手」を使いたいなら、通常の関数記法か e.currentTarget を使うのが安全です。
strict モードと this の影響(重要ポイントを深掘り)
"use strict" を使うと、「ただの関数呼び出し」で this がグローバルに落ちず undefined になります。これにより「意図せぬグローバルを書き換える」事故を防げます。
"use strict";
function f() { console.log(this); }
f(); // undefined(安全)
JavaScriptモダンな JavaScript(ES Modules など)ではデフォルトで厳格モードに近い扱いになり、this の暗黙束縛が抑制されます。基本的には strict 前提で理解するのが良いです。
まとめと使い分けの指針
thisは「どう呼んだか」で決まる。メソッド呼び出しならそのオブジェクト、newならインスタンス、ただの呼び出しなら(strict で)undefined。- メソッドを取り外すと
thisが失われる。bindで固定するか、呼び出し元を工夫する。 - アロー関数は「自分の
thisを持たず、外側のthisを使う」。メソッドの中のコールバックには便利だが、メソッド本体には通常の関数記法を使う。 - strict モードでは「ただの関数呼び出し」で
thisはundefined。意図せぬグローバル事故を防げる。
まずは「メソッド・new・ただの呼び出し・アロー」の4パターンを手で動かして、this の“手触り”を覚えると、挙動が腹落ちします。
