w123o456w
@w123o456w

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

グローバル変数と同名のローカル変数を関数内で再宣言した場合のJavaScriptの挙動について

Q&A

Closed

解決したいこと

グローバル変数として変数scopeを定義し、関数内で同名のローカル変数scopeを再宣言した場合、その関数内で再宣言される前にグローバル変数scopeにアクセスしようとすると「初期化前に「scope」にアクセスできません」のエラーが発生する。
本来はグローバル変数のscopeが参照され、”Global Variable”の出力を期待していました。
その理由についてご教授お願いいたします。

該当するソースコード

let scope = "Global Variable";

function getValue() {
    console.log(scope);  // ReferenceError:初期化前に「scope」にアクセスできません
    let scope = "Local Variable";
    console.log(scope);  // => "Local Variable"
    return scope;
}

console.log(getValue());  // => "Local Variable"
console.log(scope);  // => "Global Variable"

自分で試したこと

下記は確認済みです。
・グローバル変数名とローカル変数名が異なれば、エラーにならずグローバル変数の値を関数内から参照可能。
・同名の変数名を再宣言すること自体はスコープが異なるのでエラーにはならない。
 また、上記はストリクトモードでも検知されず、エラーにはならない。
・再宣言ではなく、代入という形であれば代入前のグローバル変数の値を参照可能

所感としては、関数内で変数を再宣言する場合、新たにローカルスコープ内の変数をメモリに割り当てていて、そのローカルスコープ内から再宣言される前のローカル変数にアクセスしようとするから「初期化前に「scope」にアクセスできません」というエラーになるのかなと。
お詳しい方、ご教授お願い致します。

0

1Answer

答え見つかりました。
JavaScriptのローカル変数は関数全体で有効になっているため、
関数が実行された時点でローカル変数scopeは有効になっているんですね。
そのため、初期化前にアクセスできないと。
で、このような挙動をJavaScriptでは「変数の巻き上げ」というらしいです。
勉強になりました。

追記で、上記のような変数の巻き上げは思わぬ不具合の原因となる可能性があるため、
ローカル変数は関数の先頭で定義するのが良いそうです。

3Like

Your answer might help someone💌