this は「今、誰のことを指しているか」を表すキーワード
this は、
「このコードを“実行している主体(オブジェクト)”は誰か?」
を指す特別なキーワードです。
よく「自分自身」と説明されますが、
JavaScript では 「どう呼ばれたか」で this の中身が変わる のがポイントです。
this は「変数」ではなく「文脈(コンテキスト)」を表すものだ、
とイメージしておくと、理解しやすくなります。
グローバルでの this(ブラウザの場合)
一番外側での this は「グローバルオブジェクト」
ブラウザ環境で、
一番外側(グローバル)で this を見るとこうなります。
console.log(this); // window(ブラウザの場合)
JavaScriptブラウザでは、
グローバルスコープの this は window を指します。
console.log(this === window); // true
JavaScriptただし、モジュール(<script type="module">)では
グローバルの this は undefined になったりするので、
「常にグローバル = this」とは限りません。
基礎としては、
「ブラウザの古典的な <script> では、外側の this は window」
くらいを押さえておけば十分です。
オブジェクトのメソッドでの this
「そのメソッドを呼び出したオブジェクト」が this になる
this が一番しっくりくるのは「オブジェクトのメソッド」の中です。
const user = {
name: "太郎",
greet: function () {
console.log("こんにちは、" + this.name + "です");
},
};
user.greet(); // こんにちは、太郎です
JavaScriptここでのポイントは、
user.greet() と呼び出したとき、greet の中の this は「user オブジェクト」を指す
ということです。
つまり、
「ドットの左側にあるオブジェクト」が this になる
と覚えると分かりやすいです。
const user1 = { name: "太郎", greet: user.greet };
const user2 = { name: "花子", greet: user.greet };
user1.greet(); // こんにちは、太郎です
user2.greet(); // こんにちは、花子です
JavaScript同じ関数 greet を使っていても、
「誰から呼ばれたか」によって this が変わる、
というのが重要なポイントです。
単なる関数呼び出しでの this
「誰からも呼ばれていない」関数の this
次のコードを見てください。
function showThis() {
console.log(this);
}
showThis();
JavaScriptこのときの this はどうなるか?
ブラウザの「非 strict モード」では、
グローバルオブジェクト(window)になります。
showThis(); // window が出る(非 strict モード)
JavaScriptしかし、"use strict" を有効にすると、this は undefined になります。
"use strict";
function showThis() {
console.log(this);
}
showThis(); // undefined
JavaScriptここが重要です。
「ただの関数呼び出し(obj.func() ではない)」では、this は“特定のオブジェクト”を指さないことが多い。
strict モードでは undefined になる。
実務では strict モードやモジュールが前提なので、
「素の関数の中の this は基本 undefined」くらいの感覚でいてOKです。
コンストラクタ(new)での this
new と一緒に呼ばれたときの this
new を使って関数を呼ぶと、
その関数は「コンストラクタ」として動きます。
function User(name) {
this.name = name;
}
const u = new User("太郎");
console.log(u.name); // 太郎
JavaScriptこのときの this は、
new User("太郎") として作られた「新しいオブジェクト」
を指します。
つまり、
コンストラクタの中の this は「今まさに作っているインスタンス」
と覚えるとよいです。
クラス構文でも同じです。
class User {
constructor(name) {
this.name = name;
}
greet() {
console.log("こんにちは、" + this.name + "です");
}
}
const u = new User("花子");
u.greet(); // こんにちは、花子です
JavaScriptconstructor の中でも、greet の中でも、this は「そのインスタンス(u)」を指します。
イベントハンドラでの this(ブラウザ)
DOM イベントでは「その要素」が this になる(古典的書き方)
ブラウザの DOM イベントで、
昔ながらの書き方をするとこうなります。
const button = document.querySelector("button");
button.addEventListener("click", function () {
console.log(this); // クリックされた button 要素
});
JavaScriptこの場合、
イベントハンドラの中の this は「イベントが発生した要素」を指します。
ただし、
アロー関数を使うと this の挙動が変わるので注意が必要です。
button.addEventListener("click", () => {
console.log(this); // ここでは button ではない
});
JavaScriptアロー関数には「自分自身の this」がなく、
外側の this をそのまま使います(これがレキシカル this)。
ここでは基礎なので、
「イベントハンドラで function を使うと、その要素が this になる」
くらいを押さえておけば十分です。
アロー関数と this(基礎だけ触れておく)
アロー関数は「自分の this を持たない」
アロー関数は、
普通の関数と this のルールが違います。
const obj = {
value: 1,
show: function () {
console.log(this.value);
},
showArrow: () => {
console.log(this.value);
},
};
obj.show(); // 1
obj.showArrow(); // undefined(期待どおりにならない)
JavaScriptshow(function)は、obj.show() と呼ばれたとき this が obj になります。
一方 showArrow(アロー関数)は、
「自分の this を持たず、定義された場所の this をそのまま使う」
という性質があります。
この例では、showArrow はグローバルスコープ(またはモジュールスコープ)で定義されている扱いなので、this は obj にはなりません。
ここが重要です。
「メソッドの this を使いたいときは、アロー関数ではなく function を使う」
というのが基礎的な鉄則です。
まとめ:初心者として this で本当に押さえてほしいこと
this は、
「今、このコードを“誰として”実行しているか」
を表すキーワードです。
特に大事なのは次の感覚です。
オブジェクトのメソッド内では、obj.method() の this は obj になる
コンストラクタ(new)の中では、this は「今作っているインスタンス」
ただの関数呼び出しでは、
strict モードだと this は undefined
アロー関数は「自分の this を持たない」ので、
メソッドの this を使いたいときには向かない
まずは、
const user = {
name: "太郎",
greet() {
console.log("こんにちは、" + this.name + "です");
},
};
user.greet();
JavaScriptこのレベルの「メソッド内の this」を、
自分の手で何度か書いて、
「ドットの左側が this」 という感覚を体に入れていくのが一番の近道です。
