JavaScriptのスコープチェーン・変数参照の仕組みをGIFアニメで分かりやすく解説

JavaScriptのスコープチェーン・変数参照の仕組み、グローバルスコープ、ローカルスコープ、ブロックスコープについてGIFアニメーションで分かりやすく解説された記事を紹介します。

JavaScriptのスコープチェーン・変数参照の仕組みをGIFアニメで分かりやすく解説

⚡️⛓JavaScript Visualized: Scope (Chain)
by Lydia Hallie

下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。

JavaScriptのスコープチェーンの仕組みをGIFアニメで分かりやすく解説

JavaScriptのスコープチェーンについてこの記事では解説します。
私は視覚学習者なので、GIFアニメで視覚的に説明することで、あなたの手助けをしようと思います😃

まずは、下記のコードを見てみましょう。

getPersonInfo関数で、name, age, cityという変数の値を含む文字列「Sarah is 22 and lives in San Francisco」を返します。しかし、getPersonInfo関数にはcityという変数は含まれていません。
では、どのようにしてSan Franciscoであることを知ったのでしょうか🤨?

このJavaScriptを実行すると、最初にさまざまなコンテキストに対してメモリスペースが設定されます。デフォルトのグローバルコンテキスト(ブラウザのwindow、ノードのglobal)、そしてgetPersonInfo関数で呼び出されたローカルコンテキストがあります。そして各コンテキストにはスコープチェーンもあります。

上記のgetPersonInfo関数の場合、スコープチェーンは下記のようになります。
心配しないでください、この図はまだ理解する必要はありません。

getPersonInfo関数におけるスコープチェーン

getPersonInfo関数におけるスコープチェーン

スコープチェーンは基本的に、その実行コンテキストで参照可能な値(他のスコープ)への参照を含むオブジェクトへの参照チェーンです。チェーン⛓は、このコンテキスト内から参照できるすべての値です。スコープチェーンは、実行コンテキストが作成されたときに作成されます、つまり実行時に作成されます!

この記事では、スコープチェーンのみに注目します。
下記の例では、実行コンテキストのキーと値のペアがスコープチェーンが持つ変数への参照を表しています。

スコープチェーンが持つ変数への参照

スコープチェーンが持つ変数への参照

JavaScriptエンジンがこれらをどのように理解するか見てましょう。
グローバルコンテキストのスコープチェーンには3つの変数、nameで値がLydia、ageで値が21、cityで値がSan Francisco、を参照しています。
ローカルコンテキストには2つの変数、nameで値がSarah、ageで値が22、を参照しています。

getPersonInfo関数の変数にアクセスしようとすると、JavaScriptエンジンは最初にローカルのスコープチェーンをチェックします。

最初にローカルのスコープチェーンをチェックする

ローカルのスコープチェーンには、nameとageへの参照があります!
nameの値はSarah、ageの値は22ですが、cityにアクセスしようとするとどうなるでしょうか?

cityの値を見つけるために、JavaScriptエンジンはスコープチェーンを辿ります。つまり、ローカルのスコープチェーンが参照している外側のスコープ(この場合はグローバルオブジェクト)で、変数cityの値を見つけることができるかを確認します。

cityがローカルにないので、JavaScriptエンジンは外側のスコープを探す

グローバルコンテキストでは変数cityを値San Fanciscoで宣言しているため、変数cityへの参照があります。これで変数の値を取得できたので、getPersonInfo関数は文字列「Sarah is 22 and lives in San Francisco」を返すことができます🎉

スコープチェーンを下ることはできますが、上ることはできません。下ではなく上と言う人もいるので混乱するかもしれませんが、言い換えると外側のスコープチェーンにはアクセスできますが、内側にはアクセスできません。
視覚化すると、滝のような動きをイメージしてください。

スコープチェーンは外側に下ることはできるが、内側に上ることはできない

スコープチェーンは外側に下ることはできるが、内側に上ることはできない

さらに深い階層でも同じです。

スコープチェーンは下るだけ

深い階層でもスコープチェーンは下るだけ

コードでも確認しておきましょう。

スコープチェーンの流れをコードで確認

スコープチェーンの流れをコードで確認

ほぼ同じですが、大きな違いが1つあります。
ここではgetPersonInfo関数でcityを宣言しただけで、グローバルスコープでは宣言していません。getPersonInfo関数を呼び出していないため、ローカルコンテキストも作成されません。

グローバルコンテキストでnameとageとcityの値にアクセスしてみます。

ReferenceErrorが返される

この場合、cityの値にアクセスすると、ReferenceErrorが返されます。
グローバルスコープでcityという変数への参照を見つけることができません。また、検索する外部スコープもなく、スコープチェーンを上に移動することもできません。

このように、変数を保護して変数名を再利用する方法としてスコープを使用することができます。

グローバルスコープとローカルスコープに加えて、ブロックスコープもあります。letまたはconstキーワードで宣言された変数は、最も近い中括弧({})にスコープされます。

これを視覚化してみます。

ブロックスコープ

ブロックスコープ

グローバルスコープ、関数スコープ、2つのブロックスコープがあります。変数は中括弧にスコープされているため、変数messageを2回宣言することができます。

まとめます。

  • スコープチェーンは、現在のコンテキストでアクセスできる値への参照のチェーンと考えることができます。
  • スコープは、スコープチェーンの下位に定義された変数名を再利用することもできます。これは、スコープチェーンの上位ではなく下位にしか定義できないためです。

スコープチェーンの説明はこれで終了です。これについてはまだ言いたいことが山ほどあるので、時間があるときに追加するかもしれません。
困っていることがあれば、遠慮なく質問してください。私はあなたを助けたいと思います!💕

sponsors

top of page

©2020 coliss