JavaScript

【JavaScript】「this」ってよく出てくるけど全然分からんわ

takahide

おはようございます。タカヒデです。

プログラミングでコードを打っていると「this」ってよく出てきますよね。

でもこの「this」を理解できていますか?

「そもそもthisってなんだ?」「thisを使う時と使わない時ってどう違うんだろう?」

そんな疑問を持たれた方もいるのではないでしょうか?

ちなみに私は全く分かりませんでした。

ということで本日は、「JavaScriptにおける、「this」について、そして、thisを指定するbind/call/applyメソッド」を紹介します。

こんな人にオススメ
  • JavaScriptにおける『「this」の使い方』が理解できない
  • 『bind/call/applyメソッド』の記載方法を知りたい

ぜひ本記事を参考にしてください。

『this』とは?

まずそもそも『this』とは何かについて解説します。

『this』とは、「どのオブジェクトを指すかを実行時に決める仕組み」のことです。

まずは簡単な例を見てみましょう。

const person = {
    name: "Takahide",
    hello: function () {
        console.log(this.name);
    }
};

person.hello();
//実行結果:Takahide

ここでの「this」は「person」を指しています。
なので「this.name」は「person.name」を指していることになるのです。

このように、「どのオブジェクトを指すかを決めている」のがthisなのです。

さらに「this」は、呼び出す場所、文脈によって中身が変化します。

『this』をどこに記載するかによって参照先が変わるものだと理解してください。

『this』の記載箇所参照先
関数やメソッドの外グローバルオブジェクト
関数の内グローバルオブジェクト
関数の内(Strictモード)undefined
オブジェクトのプロパティグローバルオブジェクト
オブジェクトのメソッド ※格納されているオブジェクト
イベントリスナーイベントの発生元
コンストラクタ生成したインスタンス
静的メンバ呼び出し元のクラス
bind/call/applyメソッド引数で指定されたオブジェクト
※アロー関数の場合は関数が定義された段階でthisを確定させる

先ほどの例は「オブジェクトのメソッド」に記載しているので、「格納されているオブジェクト」を参照しているわけですね。

なお、ブラウザにおいては、windowオブジェクトがグローバルオブジェクトとなります。

ちなみに「this」を使うべきタイミングは以下の時です。

  • オブジェクト自身のプロパティを使うとき
  • クラスのインスタンスを扱うとき
  • 同じメソッドを複数のオブジェクトで使いたいとき

「そのオブジェクト自身を参照したいとき」に使うものだと覚えておきましょう。

『this』の記載箇所による変化例

先ほど「呼び出す場所、文脈によって中身が変化する」とお伝えしました。

では具体的に『this』を記載した箇所によって参照先がどのように変化するのか見ていきましょう。

1:関数の外のthis

console.log(this);

//実行結果:Window {window: Window…}

グローバルオブジェクトを参照しています。

2:関数の内のthis

function test() {
    console.log(this);
}

test();
//実行結果:Window {window: Window…}

グローバルオブジェクトを参照しています。

3:オブジェクトのプロパティのthis

let test = {
    name: this
}

console.log(test.name);
//実行結果:Window {window: Window…}

グローバルオブジェクトを参照しています。

4:オブジェクトのメソッドのthis

let test = {
    testFunction: function () {
        console.log(this);
    }
}

test.testFunction();
//実行結果:{testFunc: ƒ}

作成したオブジェクトを参照しています。

5:イベントリスナーのthis

<p class="test">私はTakahideです</p>

let test = document.querySelector(".test");

test.addEventListener("click", function () {
    console.log(this);
});
//実行結果:<p class="test">私はTakahideです</p>

イベントを発生させた要素を参照しています。

6:コンストラクタのthis

function test(name) {
    this.name = name;
}
let Takahide = new test("Takahide");

console.log(Takahide.name);
//実行結果:Takahide

生成されたインスタンスを参照しています。

7:静的メンバのthis

class test {
    static name = "Takahide";
    static testMethod() {
        console.log(this.name);
    }
}

test.testMethod();
//実行結果:Takahide

呼び出し元のクラスを参照しています。

このように、『this』を記載する箇所によって参照先が異なっていることが分かりますね。

thisの参照先を指定するメソッド(bind/call/apply)

最後に、『bind』『call』『apply』メソッドについても紹介しておきます。

先ほどの「『this』の記載箇所と参照先の表」の中にも記載がありましたよね。

『bind』『call』『apply』メソッドとは、thisの参照先を自分で決めることができるメソッドです。

具体例で見ていきましょう。

■普通にthisを使う場合

let test = {
    name: "Takahide"
}

function show() {
    console.log(this);
}

show();
//実行結果:Window {window: Window,…}

これをcallメソッドで参照先を指定してみます。

■callメソッドで指定した場合

let test = {
    name: "Takahide"
}

function show() {
    console.log(this);
}

show.call(test);
//実行結果:{name: 'Takahide'}

このようにthisを指定することができるのですね。

ではそれぞれのメソッドの記載方法も見ていきましょう。

■bindメソッド

//bindメソッド:記載方法

関数.bind(参照先,配列ではない引数)

■callメソッド

//callメソッド:記載方法

関数.call(参照先,配列ではない引数)

■applyメソッド

//applyメソッド:記載方法

関数.apply(参照先,配列の引数)

まとめて実行してみるとこんな感じですね。

let test = {
    name: "Takahide"
}

function show() {
    console.log(this);
}

show();
//実行結果:Window {window: Window,…}

show.bind(test)();
//実行結果:{name: 'Takahide'}

show.call(test);
//実行結果:{name: 'Takahide'}

show.apply(test);
//実行結果:{name: 'Takahide'}

「show.bind(test)();」だけ()を付けるの忘れないようにしてくださいね。

通常であればグローバルオブジェクトが参照されますが、『bind』『call』『apply』メソッドを使用することで、指定したオブジェクトを参照できています。

bind/call/applyの違い

なお、『bind』『call』『apply』メソッドはそれぞれ以下の違いがあります。
参照したいものに応じて使い分けします。

記法第2引数以降
bind新たな関数を生成カンマで値を指定
callそのまま実行カンマで値を指定
applyそのまま実行第2引数が配列

bindのみ新しい関数を作っている点が異なるので注意しましょう。

まとめ

以上が「JavaScriptにおける、「this」について、そして、thisを指定するbind/call/applyメソッド」でした。

まとめ
  • 『this』とは呼び出す場所、文脈によって中身が変化する特別な変数
  • そのオブジェクト自身を参照したいときに使うもの
  • thisを指定する場合、『bind』『call』『apply』メソッドを使用

この記事が誰かの参考になれば幸いです。

お疲れさまでした。

ABOUT ME
タカヒデ
タカヒデ
ITを楽しく勉強中
通信会社の企画職で働く30代 非エンジニアでありながら半分趣味でITエンジニアリングやプログラミングを学習中 IT初心者が楽しいと思えるように発信することを目指しています ↓Xもやっているのでフォローしてね
記事URLをコピーしました