[JS]モジュール(閉)

16244 ワード

レプリカ


A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment)클로저함수와 함수가 선언된 어휘적 환경(Lexical environment)의 조합です.
ここで説明するLexicalEnvironmentは、実行コンテキストから学んだものと深く関連しているため、実行コンテキストを理解してこそ、次のコードの操作方法をより簡単に理解することができます.
次のコードを見てください.
function makeFunc() {
    let name = 'Mozilla';
    function displayName() {
      console.log(name);
    }
    
    return displayName;
}

let myFunc = makeFunc();
myFunc();
함수 makeFuncが実行されてから내부함수 displayName가 반환であれば、call stackから함수 makeFunc의 실행 컨텍스트는 제거では、関数makeFuncの変数nameも有効ではなく、変数nameにアクセスすることはできないと思います.
しかし,コードの結果は出力関数makeFuncの変数nameの値Mozillaであることが分かる.
このように외부 함수의 실행 컨텍스트가 제거 되어도 내부함수를 호출하여 외부함수의 지역변수에 접근하는 경우があります.
このときアクセスできるのは、この関数が클로저(Closure)である.

Closerによって近似可能な外部関数の領域変数を자유변수(Free variable)と呼ぶ.
`클로저``함수와 함수가 선언된 어휘적 환경(Lexical environment)의 조합`이다.
上記定義でいう「関数」は、返される内部関数を表し、「それが宣言されたときのLexicalEnvironment(LexicalEnvironment)」は、内部関数が宣言されたときのスキャンを表す.すなわち,モジュールとは,返される内部関数が自己宣言時の環境(LexicalEnvironment)を記憶し,自己宣言時の環境(Scope)以外で呼び出されてもその環境(Scope)にアクセスできる関数である.より簡単に言えば、Closerは자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수です.
  • https://poiemaweb.com/js-closure 👍
  • エンクロージャの使用例


    たとえば、ボタンをクリックするたびに、画面に表示されるカウンタにカウントが蓄積されます.

    グローバル変数を使用したカウンタ

    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <p id='count'>0</p>
        <button id='increase'>+</button>
        <button id='reset'>reset</button>
    
        <script>
          const increaseBtn = document.querySelector('#increase');
          const count = document.querySelector('#count');
    
    
          let counter = 0;
    
          function increase() {
              return ++counter;
          }
    
          const increaseCount = () => {
              count.innerHTML = increase();
          }
    
    
          increaseBtn.addEventListener('click', increaseCount);
         
        </script>
    </body>
    </html>
    上記のコードを使用しても、カウントが蓄積されていることを確認でき、問題ありません.
    しかし、下図のようにcounter는 전역 변수이기 때문에 언제든지 누구나 접근할 수 있고 변경に達することができます.このような事態を防ぐために、私たちはキャビネットの概念を使用します.


    エンクロージャのカウンタの使用

    const count = document.querySelector('#count');
    const increaseBtn = document.querySelector('#increase');
    const resetBtn = document.querySelector('#reset');
    
    let myCounter = counter();
    
    
    function counter() {
        let n = 0;
    
        return {
            count: function() { return ++n; },
            reset: function() { return n = 0; }
        };
    }
    
    const increaseCount = () => {
        count.innerHTML = myCounter.count();
    }
    const resetCount = () => {
        count.innerHTML = myCounter.reset();
    }
    
    increaseBtn.addEventListener('click', increaseCount);
    resetBtn.addEventListener('click', resetCount);      
    上のコードも同様に動作します.
    しかし、エンクロージャを介してn値を保持することもでき、以下の写真のように外部にアクセスできないため、プログラミングをより安定させることができる.
    そのため、キャビネットを十分に利用したほうがいいです.


    Reference

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
  • https://poiemaweb.com/js-closure