#はじめに
この記事は備忘録を兼ね、初学者の方を対象に書いたものです。
内容や表現に誤りがあればご指摘いただけますと幸いです。
#この記事について
JavaScriptを学んでいるとサラッとよく出てくる「this」。
なんとなくは分かるけど、少し正体がつかみにくいですね。
この記事ではそんな「this」の基本、挙動について解説します。
なお、アロー関数の中ではthisの振る舞いがまた変わりますので、
それについては今度別の記事にまとめます。
#そもそも「this」ってなに?
「this」というのはあらかじめ用意されている特別な変数です。
thisは関数の中でのみ使用されます。
ここで一度thisの基本についてざっくり説明すると、
「thisは関数のスコープ内で有効な特別な変数であり、
その関数を保持しているオブジェクトへの参照」
となります。
ちょっとよくわかりませんよね。
すごく大雑把に説明すると、thisは自身を保持している関数の親であるオブジェクトへの参照を持っています。
一応説明しますと、参照を持っているというのは、「このオブジェクトが親だよ!」という情報を持っているということです。
このthisには特徴があります。
呼び出した場所によって挙動が変わっているように見える点です。
そんな摩訶不思議なthisの振る舞いについて、
この記事では大きく4つにパターンを分けて解説します。
早速実際の例を見ていきましょう。
##メソッドの中のthis
おそらくこれが一番わかりやすく、オーソドックスなパターンではないでしょうか。
次のようなパターンですね。
const obj = {
num: 1,
method: function() {
console.log(this); //出力{{num: 1, method: ƒ}}
}
}
obj.method();
method()を保持しているobjが参照されていますね。
分かりにくいかもしれませんが{{num: 1, method: ƒ}}はobjオブジェクトの中身です。
##関数の中のthis
正しくは「グローバルスコープで定義された関数」ですね。
グローバルスコープで定義された関数の中のthisはグローバルオブジェクトを参照します。
実際に振る舞いを見てみましょう。
function func() {
console.log(this); //Window...省略
}
func();
thisはWindowを参照していますね。
このWindowが「グローバルオブジェクト」と呼ばれるものです。
グローバルオブジェクトというのはざっくり説明すると、
JavaScriptですべての関数や変数、オブジェクトを包み込む最上位のオブジェクトです。
JavaScriptではすべての要素がこのグローバルオブジェクトに格納されています。
グローバルオブジェクトが何なのかは実行する環境によって変わりますが、
ブラウザでは「window」になります。
なんだか難しく感じますが、初めから定義されているだけで普通のオブジェクトだと思ってもらって大丈夫です。
windowという名前のオブジェクトの中にプロパティやメソッドを入れていっているというイメージですね。
つまり次の二つは同じ意味になります。
function func() {
console.log('same');
}
window.func = function() {
console.log('same');
}
こうしてみると、メソッドの中のthisと同じで、関数を保持しているオブジェクトを参照しているだけですね。
違う挙動に見えるだけで、実は同じ挙動ということです。
###コンストラクタ関数の中のthis
次は少々挙動が変わります。
ですが、見慣れた形ですし直感的にわかりやすいかと思います。
newでインスタンスを生成する際、
そのインスタンス自身(新しく作られるオブジェクト自身)がthisにセットされます。
次のような形ですね。
function Person(name) {
this.name = name;
this.method = function () {
console.log('hoge');
};
}
const instance = new Person('taro');
console.log(instance.name); //出力 taro
instance.method(); //出力 hoge
// 例えば上のようインスタンスを生成した場合、下のような意味と捉えてもらうと分かりやすいかもしれません。
instance.name = 'taro';
instance.method = function () {
console.log('hoge');
};
###addEventListenerの中のthis
最後にイベント発生時のthisを見てみましょう。
これも非常に直感的に理解することができます。
addEventListenerの中のthisはイベントの発生元を参照します。
実例を見てみましょう。
document.getElementById('hoge').addEventLisetener('click', function() {
console.log(this); //<button type="button" id="hoge">button</button>
})
hogeというidが当てられているボタンを押したときにthisをコンソールに出力するコードです。
イベントのターゲットである#hogeの要素が参照されていますね。
###おわり
今回は以上になります。
冒頭でも書いたように、これがアロー関数になるとまた振る舞いが変わってきます。
それについてはまた別途書こうと思います。
参考文献
この記事は以下の情報を参考にして執筆しました。
-開眼! JavaScript 言語仕様から学ぶJavaScriptの本質 Cody Lindley 著、和田 祐一郎 訳
-JavaScriptの「this」は「4種類」?? https://qiita.com/takeharu/items/9935ce476a17d6258e27