[js]JavaScriptでのCloserとScopeの違い


スキャン


変数アクセス規則の有効範囲
Function Scope vs Global Scope
varは関数単位で、独自の役割ドメイン(Function Scope)、再宣言、再割り当てを有する.
constはletと同じ「Block Scope」を有する.
constは再宣言と再割り当てはできません.
恩を宣言できないようにする.
グローバル範囲を表すオブジェクトウィンドウ
Global Scopeで宣言された関数.
(宣言変数がvarの場合、windowオブジェクトに関連付けられます.乱発するとコンピュータが飛んでいきます...)
ただしletとconstは含まれていません.

クローズドパッケージ


クローズドパッケージ(closure)とは、内部関数が外部関数にアクセスできるコンテキストを指す.Closerは、JavaScriptを使って難易度の高いテクニックを使うために必要な概念です.
関数と宣言関数の語彙環境の組み合わせ.
この環境は、モジュールの作成時に有効な範囲内のすべての領域変数から構成されます.
コードから語彙へ:目を凝らして、「辞書式」
閉パッケージは、外部関数変数にアクセスできる内部関数です.

ここからinnerfnにアクセスできるscopeの範囲は全部で3つ(local、global、inner部分)

なぜロッカーを使うのですか?


関数(outer)に関数(inner)を書き込むと、内関数は外に書くことができません.
関数を外で使用できると凝集性が低下します.
逆に、関数に関数を書き込むと、他の要素の介入が減少します.
見ていても気持ちいいです.
また、JavaScriptがプライベート変数を記述することを可能にする良いメカニズムです.
function outer(){
    var title = 'coding everybody'; //외부함수에 정의되어진 지역변수
    function inner(){        
        alert(title); //함수 밖에서 찾는다.
    }
    inner();
}
outter();
**内部関数でtitleが定義されていない場合は、関数の外でtitleが検索されます.
すなわち,内部関数から外部関数の領域変数にアクセスできる.
これはCloserです.
function outter(){
    var title = 'coding everybody';  
    return function(){        
        alert(title);
    }
}
let inner = outter();
inner();
モジュールの重要な特性は次のとおりです.
現在のoutter()関数を内部に入れると、outter()関数の戻り値
return function(){alert(title);} 心の中に入る.
またoutter()関数は,戻りによって関数の生命を終了するようである.
重要な特徴は、内部変数を関数として実行すると、titleを再検索して外部関数の領域変数値にアクセスできることです.
すなわち、inner()は結果値「coding adbody」を実行する.

Private variable


モジュールのもう一つの特性は、変数をプライベート化することです.

なぜ変数を私有化するのですか?

  • の複数のユーザと連携した開発では、データが誰でも修正可能であれば、ソフトウェアが破壊される可能性が高いため、アクセスできないようにしなければならない.
  • 
    function factory_movie(title){
        return {
            get_title : function (){
                return title; // 지역 변수 title 가르킴
            },
            set_title : function(_title){
                title = _title // 지역 변수 title 가르킴
            }
        }
    }
    ghost = factory_movie('Ghost in the shell');
    matrix = factory_movie('Matrix');
     
    alert(ghost.get_title());
    alert(matrix.get_title());
     
    ghost.set_title('공각기동대'); //ghost의 셋 타이틀 ***
     
    alert(ghost.get_title()); // ghost셋타이틀에의해 결과 값이 바뀜 '공각 기동대'
    alert(matrix.get_title()); // 아무짓도 안해서 똑같음
    
    このようにreturn{}オブジェクトを直接使用する場合、この関数の利点は、内部のget titleメソッドとset titleメソッドからのみ領域変数titleにアクセスでき、他の人がどのようにメソッドを使用するかによって内部コンテンツが変更されないことです.

    エンクロージャの一般的な例として

    
    var arr = []
    for(var i = 0; i < 5; i++){ //return i는 이쪽 i++를 가르킨다
        arr[i] = function(){
            return i; 
        }
    }
    for(var index in arr) {
        console.log(arr[index]()); // 5만 5번 출력 
    }
    なぜ5万5回も輸出したのですか?
    arr[i]の関数()のiは()文のvariを表すからです.(呼び出し時のi値を取得します)=>i値は,まず関数内部でiを決定し,その後書き,なければ外部から探し,最終的にi値(5)を得る.
    モジュールの特性が理解されている場合は、グローバル変数iの値ではなく関数を作成し、戻り値を領域変数として使用すると、この問題を解決できます.
    var arr = []
    for(var i = 0; i < 5; i++){
        arr[i] = function(id) { 
            return function(){
                return id;  //지역변수 id를 가르킴
            }
        }(i); // **함수 바로 실행 **
    }
    for(var index in arr) {
        console.log(arr[index]()); // 0 1 2 3 4 출력
    }
    リファレンス
    https://opentutorials.org/course/743/6544
    https://developer.mozilla.org/ko/docs/JavaScript/Guide/Closures
    http://ejohn.org/apps/learn/#48
    http://blog.javarouka.me/2012/01/javascripts-closure.html