【JavaScript】関数とthisの参照先

プログラミング

えんつかです!

関数とthisの参照先について書いていきます!

以前、JavaScriptで関数を書く時にめんどくさいからアロー関数で書いちゃおってやったら上手く動作しない沼にハマってしまいました。その原因がthisの参照先が変わってしまってたからでした。なので、ざっと書いていきます!

【JavaScript】関数とthisの参照先

thisは、基本的にはメソッドの中で利用しますがthisは読み取り専用のグローバル変数のようなものでどこにでも書けちゃえます。

そして、「thisの参照先は利用する関数の呼び出し方によって変わっちゃう」ようです…

ここを理解していれば、変に詰まることはないかと思います!

関数の呼び出し方は、例えば以下のような感じです。

  • functionキーワードから始まる関数宣言 ▶︎ function fn() { }
  • functionを式として扱う関数式 ▶︎ const fn = function() { }
  • Arrow Functionを使った関数式 ▶︎ const fn = () => { }

Arrow Function以外の関数におけるthisは実行時(動的)に決まります。
Arrow Functionの関数については、関数の定義時(静的)に決まります。

Arrow Function以外の関数でのthisは「ベースオブジェクト」となります。

ベースオブジェクトとは、メソッドを呼ぶ際に、そのメソッドのドット演算子またはブラケット演算子のひとつ左にあるオブジェクトのことを指します。

例えば、

obj.method() のようなメソッドの場合は、obj.method()メソッド呼び出しのベースオブジェクトはobjオブジェクトとなり、thisはobjとなります!

ネストが深くなる場合も考え方は同じで、
obj.obj1.obj2.obj3.method()となる場合のベースオブジェクトはobj3オブジェクト(=this相当)となります!

なるほどね〜。
それじゃArrow Functionは何が違うのか?については、関数の定義時(静的)に決まります。
なんと、Arrow Function内にはthisが定義されていないのです。この時のthisは外側のスコープ(関数)のthisを指します。

…よくわからん!例見せて!


// Arrow Function定義のみ
const fn = () => {
    return this;
};
// 関数の外側に関数は存在しないのでトップレベル(global)のthisと同じ値


// 通常関数内にArrow Functionがある場合
function outer() {
    return () => {
        return this;
    }
}
// outer関数の返り値は、Arrow Functionにて定義された関数
// Arrow Functionにおけるthisはouter関数でthisを参照した場合と同じ値になる。

このように参照の仕方が変わってしまうので、利用するときは確認もしくは理解しておくのがオススメです!

以上!

ほんじゃ〜ね