JavaScript の関数定義と this の参照について

みなさんこんにちは!最近サーバサイドばかり書いていてフロントエンドが恋しい hikaru-kimi です!

前回は、JavaScript の関数定義の特徴についてご紹介いたしました!

今回は、アロー関数とその他の定義方法の大きな違いの1つでもある this の扱いについてお話したいと思います!

早速ですが、以下の2個の関数において、コンソールには何が表示されるでしょう??

例1)

this.msg = 'Hello! INGAGE, inc!';

function displayFunc1() {
    console.log(this.msg);
}

displayFunc2 = () => console.log(this.msg);

displayFunc1();
displayFunc2();

どちらも Hello! INGAGE, inc! ですね!言うに及ばずです!

では、次の例ではコンソールに何が表示されるでしょう??

例2)

let obj = {
    msg: 'Hello! INGAGE, inc!',
    displayFunc1: function () {
        console.log(this.msg);
    },
    displayFunc2: () => {
        console.log(this.msg);
    }
};

obj.displayFunc1();
obj.displayFunc2();

どうせ両者とも同様に Hello! INGAGE, inc! でしょ?と思ったあなた!是非この記事を読んで一緒に勉強しましょう!

正解は以下の通りとなります。

obj.displayFunc1();
=> Hello! INGAGE, inc!

obj.displayFunc2();
=> undefined

瞬殺できた方、以下の文章は読み飛ばして是非とも弊社採用サイトよりご応募くださいませ!

なぜ宣言方式による関数とアロー関数とで出力される結果が異なるかと言いますと、定義方法で参照する this が異なるからです。

結論から先に述べますと、

宣言方式の関数・無名関数では、this定義時のものを参照します。

今ひとつアロー関数では、this関数実行時のものを参照します。

このような違い故、例2では同じ obj オブジェクト内の関数にも関わらず、コンソールへの出力結果が異なってしまったのです!!

例2を元に敷衍しますと、obj.displayFunc1() 実行時に関数内で参照される this は、定義時this となるため obj となります。

関数内の this.msg はつまるところ obj.msg となりますので、期待通り Hello! INGAGE, inc! が参照されます。

一方の obj.displayFunc2() 実行時に関数内で参照される this は、実行時this となります。

実行箇所は obj オブジェクト内ではありませんので、thisobj とはなりません。

上記例2において this はグローバルオブジェクトとなりますので、実行環境がブラウザ上であれば window オブジェクトとなります。

window オブジェクトにはデフォルトで msg なる要素はありませんので、window.msg を参照しても undefined となる、という仕組みなのです!

以上、関数の定義方法によって参照する this が異なるということについてまとめてみました!

ただ、JavaScript 初級者の方々からすると、そもそも this の概念をちゃんと理解できてない方も多いのではないでしょうか?

かく言う私も、開発初期の方はなんとなく this を扱ってきてしまい、期待する結果が得られないこともしばしばありました。

ということで、JavaScript における this について総合的に整理しようと思ったのですが、もう終業時刻が差し迫ってきてしまいましたので今日はこの辺で!

this の扱いについてはまた次回にて!乞うご期待!

弊社インゲージでは、JavaScript の概念を一つ一つ丁寧に理解し、コードとして適切に表現できるエンジニアを募集しております。

フロントエンドエンジニアは比較的少数しか在籍しておりませんので、設計からご自身の思想を反映させることも十二分に可能です。

ご興味を持たれた方、以下のリンクよりご応募をお願いいたします。