[モダンJavaScript Deep Dive]-14グローバル変数の問題
6026 ワード
14.1変数のライフサイクル
14.1.1地域変数のライフサイクル
変数には生成と消失のライフサイクルがあります.
グローバル変数のライフサイクルは、アプリケーションのライフサイクルと同じです.
ゾーン変数のライフサイクルは、関数のライフサイクルと一致します.
前の4.4節「変数宣言の実行時間と変数反発」では、宣言がどこにあるかにかかわらず、変数宣言が最初に実行されます.しかし、厳密には、これはグローバル変数に限られる.
変数のライフサイクルは、メモリ領域から解放され、使用可能なメモリプールに戻る時間です.
変数は、自分が登録したスキャンプログラムが破棄されるまで有効です.割り当てられたメモリ領域が誰にも参照されなくなると、ゴミ収集器によって解放され、使用可能なメモリプールに戻されます.
この点スコフも同じだ.スコフを参照する人がいれば、スコフは消えずに生きていく.
前の例を見てみましょう
var x = 'global';
function foo(){
console.log(x); // (1)
var x = 'local';
}
foo();
console.log(x); // (2)
foo関数内部で宣言された領域変数xは(1)点で未定義に初期化されている.したがって,(1)グローバル変数ではなく領域変数xを参照して値を出力する.このように、オフセットはスキャン単位で動作し、グローバル変数と領域変数のオフセットを比較すると、以下のようになります.
14.1.2グローバル変数のライフサイクル
関数とは異なり、グローバルコードは明示的な呼び出しなしで実行されます.すなわち,グローバルコードは特にエントリポイントがなく,コードがロードされるとすぐに解釈され実行される.また、戻り文は使用できないため、最後の文が実行され、実行する文がなくなった場合に終了します.
varキーワードとして宣言されたグローバル変数は、グローバルオブジェクトのpropertyとなります.
グローバルオブジェクト(グローバルオブジェクト)とは?
전역객체와 표준 빌트인 객체에 대해서는 21장 "빌트인 객체"에서 자세히 살표보도록 한다.
ブラウザ環境では、グローバルオブジェクトはwindowなので、ブラウザ環境でvarキーワードとして宣言されるグローバル変数は、グローバルオブジェクトwindowのpropertyです.グローバルオブジェクトウィンドウは、Webページを閉じる前に有効です.したがって、ブラウザ環境でvarキーワードとして宣言されたグローバル変数は、Webページを閉じる前に有効です.
すなわち、varキーワードで宣言されるグローバル変数のライフサイクルは、グローバルオブジェクトのライフサイクルと一致する.
14.2グローバル変数の問題
グローバル変数はスキャンチェーン上の終点に存在し、変数を検索すると最後に検索されます.すなわち,グローバル変数の探索速度が最も遅い.
14.3グローバル変数を無効にする方法
上記の問題を理由に、グローバル変数の使用をできるだけ抑制し、地域変数を使用する必要があります.また,変数のスキャンは狭いほどよい.
グローバル変数の使用を抑制する方法は次のとおりです.
14.3.1即時実行関数
関数定義と同時に呼び出されるインスタント実行関数は1回のみ呼び出されます.次の例に示すように、すべてのコードが即時実行関数に囲まれている場合、すべての変数は即時実行関数の領域変数になります.
(function () {
var foo = 10;
}());
console.log(foo); // ReferenceError: foo is not defined
14.3.2名前空間オブジェクト
方法は、グローバルにネーミングスペースの役割を果たすオブジェクトを作成し、グローバル変数として使用したい変数をpropertyに追加することです.
var = {}; //전역 네임스페이스 객체
MYAPP.name = 'AN';
console.log(MYAPP.name); //AN
ネーミングスペースを分離すると識別子の競合を防止できますが、ネーミングスペースオブジェクト自体がグローバル変数に割り当てられるため、あまり役に立ちません.14.3.3モジュールモード
モジュールモードはクラスを模倣し,関連する変数と関数を集合させ,即時実行関数で包み,モジュールを形成する.モジュールモードはJavaScriptの強力な機能モジュールに基づいています.モジュールモードの特徴は,グローバル変数の2日前だけでなくカプセル化も可能であることである.
モジュールモードについては、モジュールについて説明する必要があります.これは、24章の「モジュール」で詳しく説明します.現在の段階では、「シャーシ」という機能がグローバル変数を抑制できることに注意します.
パッケージとは,オブジェクトの状態を表すプログラムと操作可能な動作方法を組み合わせたものである.カプセル化は、情報非表示と呼ばれるオブジェクトを非表示にするための特定のプログラムまたは方法です.
オブジェクト向けのプログラミング言語の多くは、公開範囲を限定するために、公開、プライベート、保護されたアクセス制限者などを使用することができます.ただし、JavaScriptではアクセス制限はありません.
モジュールモードは,グローバルネーミング空間汚染を防止する機能だけでなく,限られているが,情報隠蔽を実現するために用いられる.
var Counter = (function () {
var num = 0;
return {
increase() {
return ++num;
},
decrease() {
return --num;
}
};
}());
console.log(Counter.num); // undefined
console.log(Counter.increase()); // 1
console.log(Counter.increase()); // 2
console.log(Counter.decrease()); // 1
console.log(Counter.increase()); // 2
上記の例では、返されるオブジェクトのPropertyは共通メンバーであり、numなどの外部からアクセスできない変数や関数はプライベートメンバーです.14.3.4 ES 6モジュール
ES 6モジュールは、ファイル自体の独立したモジュールスキャンを提供する.
ES 6モジュールを使用すると、グローバル変数は使用できなくなります.したがって、モジュールでvarキーワードとして宣言された変数はグローバル変数ではなく、windowオブジェクトのpropertyではありません.
<script type="module" scr="A.mjs"></script>
<script type="module" scr="B.mjs"></script>
例に示すように、type=「module」コメントを追加すると、ロードされたファイルがモジュールとして実行され、拡張子はmjsを推奨します.ES 6モジュールはIEを含む旧式ブラウザでは機能せず、利用可能であっても変換またはバンドルが必要であるため、通常Webpackなどのモジュールバンドルパッケージが使用される.
モジュールやWebpackなどのモジュールバンドルパッケージの導入方法は,48章「モジュール」と49章「BarelとWebpackを用いてES 6+/ES.NEXT開発環境を構築する」で議論する.
Reference
この問題について([モダンJavaScript Deep Dive]-14グローバル変数の問題), 我々は、より多くの情報をここで見つけました https://velog.io/@aneb/모던-자바스크립트-Deep-Dive-14-전역-변수의-문제점テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol