【クイズでわかる】JavaScriptのthisとは?なぜ呼び出し方によって指すものが変わるのか

こんにちは!Reiです‎(˵ •̀ ᴗ – ˵) ✧


JavaScript の this って、ややこしいですよね…!
同じ this でも、コードの書き方というより どう呼び出されたか で指す相手が変わるってとこがイマイチ難しい部分 (。-`ω´-)ンー


今回は、this がどこを指すのかをクイズ形式で理解を深めていきます!

迷子になりやすいところなので、ぜひ1つずつ確認してみてください ᥫᩣ ̖́-


第1問 メソッドの中の this

まずはここから!

const cat = {
  name: "ハチワレ",
  greet: function() {
    console.log("僕は " + this.name);
  }
};

cat.greet();

このコードを実行すると、何が表示されるでしょうか?

  1. “僕は ハチワレ”
  2. “僕は undefined”
  3. エラーになる

正解は… (ここをクリック!)

1の "僕は ハチワレ" です!


解説 !!

これが this の基本的な形。

関数がオブジェクトの中にあって、 オブジェクトから呼び出されたときthis はそのメソッドを呼び出したオブジェクトのことを指します。


今回なら、cat.greet(); と呼んでいるので、this は同じオブジェクト内の cat のことを指します。


「メソッドを誰が呼んだのか」を見ることが、this を考えるときの最初のポイントです 👀


第2問 アロー関数を使うと?

次はこちら!

const dog = {
  name: "ポチ",
  greet: () => {
    console.log("僕は " + this.name);
  }
};

dog.greet();

この結果はどうなるでしょうか?

  1. "僕は ポチ"
  2. "僕は undefined" のような結果になる
  3. 必ずエラーになる

正解は… (ここをクリック!)

2の "僕は undefined" のような結果になる、です!
(ここが this の最大の罠かも…!)


解説 !!

アロー関数は、普通の関数みたいに呼び出し方によって this が決まらないのです。


アロー関数は自分専用の this を持たず、定義された場所の外側の this をそのまま引き継ぎます。

なので今回の

greet: () => {
  console.log("僕は " + this.name);
}

では、同じオブジェクト内の dog を見てくれません。
そのため、期待していた dog.name ではなく、外側の this.name を見に行ってしまいます 💦


なので、「呼び出し元によって this を変えたい場合」は function を使うのが基本となります!


第3問 イベントリスナーの this

次はこちら!

button.addEventListener("click", function() {
  console.log(this);
});

ボタンをクリックしたとき、
この this は何を指すでしょうか?

  1. window
  2. クリックされたボタン自身
  3. undefined

正解は… (ここをクリック!)

2の「クリックされたボタン自身」です!


解説 !!

this は関数そのものではなく、どう呼び出されたか で決まります。


イベントリスナーで function() {} の形を使った場合、this にはイベントが発生した要素が入るります。

つまり今回なら、

button.addEventListener("click", function() {
  console.log(this);
});

の this は、そのクリックされた button 要素のことを指します。


ただし、ここでアロー関数にしてしまう、その場で決まる this ではなく、このコードの外側で使われている this を使ってしまうので意味が変わってしまいます 💦

この違いはかなり間違いやすいので、イベント処理では「function を使うか、アロー関数か」で this が変わる点に要注意です!


第4問 new を使うと?

最後の問題はこちら!

function Cat(name) {
  this.name = name;
}

const myCat = new Cat("ハチワレ");
console.log(myCat.name);

このとき、Cat の中の this は何を指しているでしょうか?

  1. window
  2. 新しく作られたオブジェクト
  3. 関数 Cat 自身

正解は… (ここをクリック!)

2の「新しく作られたオブジェクト」でした!


解説 !!

new を使って関数を呼び出すと、その関数はコンストラクタとして動きます。

コンストラクタとは、新しいオブジェクトを作るために使う関数のことです。


このとき JavaScript の内部ではざっくり、

  1. 新しい空のオブジェクトを作る
  2. そのオブジェクトを this として扱う
  3. this.name = name のように値を入れる
  4. 最後にそのオブジェクトを返す

という流れが起きています。

なので、

const myCat = new Cat("ハチワレ");

で呼び出された Cat の this は、新しく作られた myCat 側のオブジェクトを指しているんです。


ここまでのポイントおさらい !!

今回の内容をまとめると、次のとおり↓

this の基本
this は書かれた場所だけでは決まらない
・どう呼び出されたかで指す相手が変わる
・まずは「誰がその関数を呼んだか」を見る

メソッドの this
・オブジェクトからメソッドを呼ぶと、そのオブジェクトのことを指す
・ドットの左側を見ると整理しやすい

アロー関数の this
・自分の this を持たない
・外側の this をそのまま使う
・メソッドには不向きなことが多い

new の this
・新しく作られたオブジェクトを指す
・コンストラクタ的な使い方でよく出てくる


this は見た目だけでは判断しにくいですが、「この関数はどう呼ばれたのか」で見てみると this が指している値がわかりやすくなります 💡

特にメソッド、アロー関数、new の3つを分けて考えてみてくださいね 👀


最後に

this はあまり頻繁に書かないぶん、急に出てくると悩みやすい箇所でもあります。

特に最初はこの3つを押さえるだけでもかなり変わってくるかなと思います 👀

・オブジェクトからメソッドを呼ぶと、そのオブジェクトのことを見る
・アロー関数は外側の this を使う
new のときは新しいオブジェクトを指す

this はややこしく考えがちですが、1つずつ「どう呼ばれたか」を確認して扱っていきましょう!

コメント

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