JavaScript | 基礎構文:スコープ・実行コンテキスト - this の基礎

JavaScript JavaScript
スポンサーリンク

this は「今、誰のことを指しているか」を表すキーワード

this は、
「このコードを“実行している主体(オブジェクト)”は誰か?」
を指す特別なキーワードです。

よく「自分自身」と説明されますが、
JavaScript では 「どう呼ばれたか」で this の中身が変わる のがポイントです。

this は「変数」ではなく「文脈(コンテキスト)」を表すものだ、
とイメージしておくと、理解しやすくなります。


グローバルでの this(ブラウザの場合)

一番外側での this は「グローバルオブジェクト」

ブラウザ環境で、
一番外側(グローバル)で this を見るとこうなります。

console.log(this); // window(ブラウザの場合)
JavaScript

ブラウザでは、
グローバルスコープの thiswindow を指します。

console.log(this === window); // true
JavaScript

ただし、モジュール(<script type="module">)では
グローバルの thisundefined になったりするので、
「常にグローバル = 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" を有効にすると、
thisundefined になります。

"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(); // こんにちは、花子です
JavaScript

constructor の中でも、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(期待どおりにならない)
JavaScript

show(function)は、
obj.show() と呼ばれたとき thisobj になります。

一方 showArrow(アロー関数)は、
「自分の this を持たず、定義された場所の this をそのまま使う」
という性質があります。

この例では、
showArrow はグローバルスコープ(またはモジュールスコープ)で定義されている扱いなので、
thisobj にはなりません。

ここが重要です。
「メソッドの this を使いたいときは、アロー関数ではなく function を使う」
というのが基礎的な鉄則です。


まとめ:初心者として this で本当に押さえてほしいこと

this は、
「今、このコードを“誰として”実行しているか」
を表すキーワードです。

特に大事なのは次の感覚です。

オブジェクトのメソッド内では、
obj.method()thisobj になる

コンストラクタ(new)の中では、
this は「今作っているインスタンス」

ただの関数呼び出しでは、
strict モードだと thisundefined

アロー関数は「自分の this を持たない」ので、
メソッドの this を使いたいときには向かない

まずは、

const user = {
  name: "太郎",
  greet() {
    console.log("こんにちは、" + this.name + "です");
  },
};

user.greet();
JavaScript

このレベルの「メソッド内の this」を、
自分の手で何度か書いて、
「ドットの左側が this」 という感覚を体に入れていくのが一番の近道です。

タイトルとURLをコピーしました