JavaScriptの変数スコープを理解する
スコープは、変数または関数の実行コンテキストです。 アクセスできるデータを定義します。 この概念はかなり単純に見えるかもしれませんが、いくつかの重要な微妙な点があります。
JavaScriptには、従来、グローバルスコープとローカルスコープの2種類のスコープがありました。 スコープの目的は、実行コンテキストがアクセスできるすべての変数と関数へのアクセスを提供することです。
グローバルスコープ
変数が関数の外部で宣言されると、その変数は自動的にグローバルスコープに属し、関数であれブロックであれ、プログラムのどこからでもアクセスできます。 また、必要に応じて、ブラウザでグローバル変数を次のように宣言することで作成できます。 window.newVariable
プログラムの任意の場所。
const nestAnimal = 'crocodilian'; // belongs to the Global scope
function getNestInfo(){
window.eggs = 5; // as well belongs to the Global scope
}
実際、ブラウザでは、グローバルスコープの変数はグローバルに属します window
物体。
JavaScriptはガベージコレクションされた言語であり、コンテキストでプログラムを実行している間、すべての変数を利用可能に保ち、後で削除します。 変数のライフサイクルを考えてみましょう。 変数は、関数の実行中に存在します。 変数は関数内で使用され、関数は終了します。 その時点で、この変数は不要になったため、そのメモリを再利用でき、JavaScriptによってこの変数がメモリから削除されます。 ただし、グローバル変数は、アプリケーションの実行中は常にメモリに残り、アプリケーションを詰まらせるため、プログラムの速度が低下します。また、予期しない名前の競合が発生する可能性があります。
つまり、可能な限り、グローバル変数の定義を避ける必要があります。 これらは非常に特殊な場合にのみ本当に必要になるため、これには注意してください。
ローカルスコープ
ES6は、constおよびletキーワードを使用してブロックスコープ変数を導入しました。 これらのキーワードを使用すると、ローカルスコープが作成され、それを囲む最も内側のブロック内に存在します。 それは関数かもしれません、 for
ループ、 while
ブロック、 if
ブロックなど このようなローカルスコープの変数には、そのブロック内からのみアクセスできます。
各ブロックには独自の実行コンテキストがあり、アクセスできるデータとその動作を定義します。 コードがコンテキストで実行されると、スコープチェーンが作成されます。 これには、そのブロック内で宣言されたすべての変数と関数が含まれ、次に、含まれている(親)コンテキストからのデータなどが含まれます。 このパターンは、グローバルコンテキストに到達するまで続きます。
例を見てみましょう:
let caymanMood = 'calm';
function changeMood(newMood){
if (caymanMood === 'calm'){
caymanMood = newMood;
} else {
caymanMood = 'calm';
}
}
changeMood('happy');
関数 changeMood
2つのオブジェクトを含むスコープチェーンがあります:それ自体の変数オブジェクト(引数オブジェクト newMood
)およびグローバルコンテキストの可変オブジェクト caymanMood
. 関数はにアクセスできます caymanMood
スコープチェーンの一部だからです。
スコープチェーン拡張
グローバルおよびローカルの実行コンテキストに加えて、スコープチェーンを拡張することが可能です。 これは2つの方法で実行できます。
- ポイント1:withステートメント
- ポイント2:
catch
でブロックtry...catch
声明。
function buildNest() {
const assets = 'grass';
with(reptilian){
const building = ability + assets;
}
return building;
}
with
スコープチェーンの先頭に追加されるオブジェクトを作成しますが、コードを読んだときに、どのオブジェクトが正確に変更されるかを確実に知ることはできません。 それはグローバル変数になりますか ability
またはこのコンテキストの変数 reptilian.ability
. したがって、プログラムの正しい実行は保証されません。 の使用 with
このステートメントは、 MDN Web docs によって推奨されていません。これは、紛らわしいバグや互換性の問題の原因となる可能性があるためです。
The catch
ステートメントは、スローされたエラーオブジェクトの宣言を含む新しい変数オブジェクトを作成し、このエラーオブジェクトはスコープチェーンの先頭に追加されます。
まとめ
これにより、JavaScriptでローカルスコープとグローバルスコープがどのように機能するか、そして可能な限り最も近いローカルコンテキストに依存することが、読みやすく保守しやすいコードを作成するための良いアイデアであるかを少しよく理解できるはずです。