レプリカ


レプリカ


JavaScriptでは、関数は宣言時に自分がアクセスできる範囲を決定し、覚えています.
これを語彙scope(Lexical Scope)と呼び、この語彙scopeによって
外部関数環境の内部関数がClosureであることを覚えておいてください.
closureが内部変数を参照する場合、
Garbage Collectorは、内部変数によって消費されるメモリを回収しません.
closureを使用して終了したら、参照を削除したほうがいいです.

左の右f 1()という関数を定義します.var a = 1;-この関数には、関数内でしか使用できない変数aがあります.3.var a = f1();によってf1()関数が呼び出され、戻り値が返されます.4変数aの有効性は、戻り値と関数が終了するために終了する.関数内変数のライフサイクルは、関数内で変数を生成しreturnで終了する前に行われます.関数が終了すると、f 1()が所有するすべてのリソースが解除されます.(=Garbage Collectorによって収集されます.)1.f1()関数を呼び出すと、f2()関数オブジェクト(object)が返されます.var f = f1();var a = f();によってf1()関数が呼び出され、実行され、関数は値を返し、終了する.この時、自分が持っているすべての資源を廃棄しなければならない.ただし、戻り値のf2()関数では、終了した関数f1()にある戻りたいa値を検索します.return関数f2()では、語彙scope(LexicalScope)で記憶されているf1()の領域変数aを使用する必要があるため、f1()関数は終了しても、その所有するリソースを破棄することはできない.var fがnullを戻り値で受け入れるか、または他の関数に置き換えられない場合、f1()関数の生命は継続します.(=Garbage Collectorによって回収されず、メモリに残っています.)5.2467912関数は、f2()が所有するリソースを閉じる唯一のキーワードclosureです.

利用モジュール


1)Clousareによるパッケージング(エンクロージャによる非表示)

function Hello(name) {
  this._name = name;
}

Hello.prototype.say = function() {
  console.log('안녕, ' + this._name);
}

var hello1 = new Hello('해리포터');
var hello2 = new Hello('론위즐리');


hello1.say(); // '안녕, 해리포터'
hello2.say(); // '안녕, 론위즐리'

hello1._name = 'anonymous';
hello1.say(); // '안녕, anonymous'
hello()で生成されたオブジェクトhello 1とhello 2には、nameという変数があります.
変数名に下線を付け、「この変数を専用変数として使用したい!」マークしたけど.
実際、これは依然として外部からも近づきやすい変数です.
外部からhello 1.name=anonymous経由
hello 1()関数のhello 1.nameに「anonymous」を割り当てると、
その値の変化から,隠匿化は失敗した.
function Hello(name) {
  var _name = name;
  return function() {
    console.log('안녕, ' + _name);
  };
}

var hello1 = Hello('해리포터');
var hello2 = Hello('론위즐리');


hello1(); // '안녕, 해리포터'
hello2(); // '안녕, 론위즐리'

  return function() {
    console.log('안녕, ' + _name);
  };
上記の閉パケットはhello()関数内に作成されます.
hello 1、hello 2関数を呼び出し、実行後に関数を終了します.
hello 1、hello 2にアクセスできるリソースは、内部で返される関数のみです.
外部ではnameという変数にアクセスできません.
変数nameをclosureでカプセル化(非表示).

2)async function call in loop(繰り返し文で非同期関数を呼び出す)

for (var i = 0; i < 10; i++) {
  setTimeout(function() {
    console.log(i);
  }, 100);
}
これは0-9の整数を出力するために書かれたコードです.
しかし実際に運転すると10万10回出力されます.

単一スレッド言語JavaScriptは、タスクを呼び出しスタックにプッシュし、処理するたびに1つポップアップします.
settimeoutは非同期タスクであるため、呼び出しスタックではなくイベントキューに格納されます.
callスタックが空の場合、イベントループはイベントキュー内のタスクにプッシュされます.
settimeoutが受信した匿名コールバック関数を実行します.
しかし,計算機の計算速度は非常に速く,0.1秒未満までに反復サイクルが完了した.
次にsettimeoutのコールバック関数を呼び出し、すでに10のiを参照します.
for (var i = 0; i < 10; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(j);
    }, 100);
  })(i);
}
反復文の関数をインスタント実行関数として作成
settimeout()の匿名関数を閉パッケージにします.
closureは自分が作った環境を覚えています.
closureが作成されると、繰り返し文でiの値を変更します.
closureは10回繰り返した10の異なる環境を覚えています.
このiをparameter jとして受信すると、これらの値は動的変更時に反映されます.
私たちが望んでいる結果を得ることができます.

+)以上の即時実行関数の記述方式は以下のコードと同じである.
for (var i = 0; i < 10; i++) {
    function call(j) {
        setTimeout(function () {
            console.log(j);
        }, 100);
    }
    call(i);
}
参考資料
YouTube-1
YouTube-2
[JavaScript]Closerとは?
[JavaScript]javascriptモジュールの意味と使用理由
JavaScriptモジュール(Close)