[JS]モジュール


エンクロージャ


関数と宣言関数のディレクトリ環境の組合せ
関数が生成されるとscopeが存在し、関数は呼び出される前に自分の[[environment]内部スロットを知っていた.(Lexical Environment――自分を呼び出した場所(静的スキャン)で親スキャンを決定するのではなく、自分を宣言した場所で親スキャンを決定します.)
つまり,自分の親スキャンプログラムを覚えているので,外部で参照しても[[environment]でアクセスできる.

実行コンテキストスタックでOuter関数がポップアップされると、ゴミ収集器が起動し、メモリから解放されます.ただし、グローバル変数のconst innerFuncはinner関数を参照するため、innerを指す[environment]のouterもゴミ収集器のターゲットから離れます.
上記の重畳関数をCloserと呼びます.

エンクロージャの条件になる可能性があります


前述したように、MDNでは、モジュールは함수와 함수가 선언되는 렉시컬 환경として定義される.JSでは、関数はすべて自分の位相鏡を知っているので、JSはすべてCloserと呼ぶことができますか?
理論的には正しいが、通常は閉鎖器とは呼ばない.
  • ネスト関数は外部関数よりも永続的
  • 少なくとも1つの親ミラー変数を参照する必要があります.
  • function foo() {
      const x = 1;
      function bar() {
        console.log(x);
      }
      bar();
    }
    
    foo();
    
    上記の例では、barは、その上位scopeにあるx−fooの−を参照する.では、これをCloserと呼んでもいいですか?
    変数のライフサイクルを考慮すると、barを返さずにfooを呼び出すため、barのライフサイクルはfooより短い.したがってCloserとは呼べません.

    モジュールが使用可能な場合!


    ステータスの安全な変更と保守
    純粋な関数(外部の状態を変更しない関数)を指す必要がありますが、キャビネットを介して意外に状態を変更することは避けられます.-特定の関数のみがステータスを変更できます

    グローバルに宣言されたnum値がupnumという関数で変更された場合、これは純粋でない関数であるため、回避する必要があります.

    このように直ちに実行関数に変更すると、upnumのreturn内の関数の[[environment]が依然として存在する可能性があるため、num値の置き換えを続行できます.

    モジュール=即時実行関数?

    // 함수를 인자로 전달받고 함수를 반환하는 고차 함수
    // 이 함수가 반환하는 함수는 클로저로서 카운트 상태를 유지하기 위한 자유 변수 counter을 기억한다.
    function makeCounter(predicate) {
      // 카운트 상태를 유지하기 위한 자유 변수
      var counter = 0;
      // 클로저를 반환
      return function () {
        counter = predicate(counter);
        return counter;
      };
    }
    
    // 보조 함수
    function increase(n) {
      return ++n;
    }
    
    // 보조 함수
    function decrease(n) {
      return --n;
    }
    
    
    const increaser = makeCounter(increase);
    console.log(increaser()); // 1
    console.log(increaser()); // 2
    
    
    const decreaser = makeCounter(decrease);
    console.log(decreaser()); // -1
    console.log(decreaser()); // -2
    
    直ちに関数を使用する例とは異なり、パラメータがincreate、reduce(関数)の場合はnewが2回呼び出されるため、実行コンテキストでmakeCounterが2回呼び出される.これによりincreserのcounterとreduce counterのscopeが変更されるため,変更が相互に関連付けられないという問題がある.

    これに対して、インスタント実行関数は呼び出しスタック(実行コンテキストスタック)に入る関数と同じですが、newで呼び出す必要はありません.そのため、ディレクトリ環境が同じになる可能性があります.
    const counter = (function(){
      let num = 0 ;
      return{
        increase(){
          return ++num;
        }
        decrease(){
          return --num;
        }
    };
    } ());
    new counter()console.log(counter.increase())の代わりにconsole.log(counter.decrease())を使用すればよい.

    n/a.結論


    要するに、私の考えはCloserを使うことを奨励すべきです!!
    全く違いますが、JavaではJAVAという言葉が前に似ていると考えられていますのでprivateで情報を隠すことができますが、JavaScriptではこれらすべてprivateなので情報を隠すことはできません.しかし、パレットによってpublicを大まかに模倣することができる.
    しかし、100%の情報を完全に隠すことができるわけではありません.
    poiemaweb-モダンJavaScript,パッケージ