【JavaScript】「this」ってよく出てくるけど全然分からんわ
おはようございます。タカヒデです。
プログラミングでコードを打っていると「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メソッド | 引数で指定されたオブジェクト |
先ほどの例は「オブジェクトのメソッド」に記載しているので、「格納されているオブジェクト」を参照しているわけですね。
なお、ブラウザにおいては、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』メソッドを使用
この記事が誰かの参考になれば幸いです。
お疲れさまでした。
