(JS)グローバル変数の問題


変数のライフサイクル


変数は宣言によって生成され、割り当てによって値が取得されます.そして、いつの日かゴミ車に消されます.つまり、変数にはライフサイクルがあります.
グローバル変数のライフサイクルは、アプリケーションのライフサイクルと同じです.ただし、関数内部で宣言された領域変数は、関数が呼び出されたときに作成され、関数の終了時に破棄されます.
function foo() {
  let x = 'local';
  console.log(x); // local
  return x;
}

foo();
console.log(x); // ReferenceError: x is not defined
領域変数xは、関数fooが呼び出されるまで生成されません.関数が終了すると、領域変数も消え、ライフサイクルが終了します.すなわち、領域変数は、関数が呼び出されて実行される間にのみ有効である.

グローバルvarキーワード

var키워드と宣言されたグローバル変数は、グローバルオブジェクトのpropertyになります.
ブラウザ環境では、グローバルオブジェクトはwindowなので、ブラウザ環境でvar키워드と宣言されたグローバル変数はwindowのpropertyになります.
このグローバルオブジェクトウィンドウは、ウェブページの終了時に有効であり、グローバル変数var키워드は、ウェブページの終了時に有効である.

グローバル変数宣言の問題


1.暗黙結合


グローバル変数は私の意図とは異なり、どこでもグローバル変数を参照および変更できます.
これは暗文結合を可能にし,変数の有効範囲が大きいほどコードの可読性が悪くなり,何気なく状態を変える可能性がある.

2.長生きサイクル


グローバル変数のライフサイクルは、プログラムの終了時間とほぼ一致しており、ステータス変更の機会が増加します.思わぬミスが起こる可能性が高い.

3.走査チェーン上に存在する終点


グローバル変数は、スキャンチェーン上の終点に存在します.これは、変数を検索すると、グローバル変数が最後に検索されることを意味します.最終的には、グローバル変数の検索速度が最も遅いことを意味します.

4.ネーミングスペース汚染


JSの最大の問題は、.jsファイルが別々であっても、グローバルスキャンを共有することである.狭葉を行うと,グローバル変数名で競合する確率が高い.

グローバル変数を無効にするには:


変数のスキャンは狭いほど良い.

1.即時実行関数


関数の定義と呼び出しを同時に実行します.すべてのコードが即時実行関数に囲まれている場合、すべての変数は即時実行関数の領域変数になります.この特性はグローバル変数の使用を制限する方法でもある.
(function () {
  var foo = 10; // 즉시 실행 함수의 지역 변수
  // ...
}());

console.log(foo); // ReferenceError: foo is not defined

2.ネーミングスペースオブジェクト


名前の通り、ネームスペースオブジェクトはNameSpaceの役割を果たすオブジェクトを作成し、グローバル変数として使用したい変数をpropertyに追加する方法です.
let nameSpace = {}; // 전역 네임 스페이스 객체

nameSpace.person = {
  name: 'Yang',
  address: 'seoul'
};

console.log(nameSpace.person.name); // Yang
ネーミングスペース内にオブジェクトを作成し、階層的に使用できます.
ネーミングスペースを分離すると、識別子の競合を防止できますが、ネーミングスペースオブジェクト自体がグローバル変数に割り当てられるため、あまり役に立ちません.

3.モジュールモード


クラスを模倣することで,関連する変数と関数を集合させ,直ちに実行関数で囲み,モジュールを形成する.
モジュールモードはJSの強力な機能モジュールに基づいている.これにより、グローバル変数の抑制とパッケージングを実現することもできる.
帽子をかぶせる
非公開情報(非表示情報)
モジュールモードは,グローバルネーミング空間汚染を防止する機能を有するだけでなく,限られているが,カプセル化を実現するために用いられる.
// 변수에 즉시 실행 함수 할당
var Counter = (function () {
  // private 변수
  var num = 0;

  // 외부로 공개할 데이터나 메소드를 프로퍼티로 추가한 객체를 반환한다.
  return {
    increase() {
      return ++num;
    },
    decrease() {
      return --num;
    }
  };
}());

// private 변수는 외부로 노출되지 않는다.
console.log(Counter.num); // undefined

console.log(Counter.increase()); // 1
console.log(Counter.increase()); // 2
console.log(Counter.decrease()); // 1
console.log(Counter.decrease()); // 0

4.ES 6モジュール


グローバル変数の氾濫を抑制するために、ES 6が導入したモジュールを使用することができる.