レプリカ

16010 ワード

Closerとは?
Closerとは独立(自由)変数の関数です.モジュールで定義した関数は、作成した環境を覚えています.
簡単に言えば、関数の定義と使用はモジュールです.しかし、定義された関数が返され、外部で使用されることが多い.
function getClosure() {
  var text = 'variable 1';
  return function() {
    return text;
  };
}

var closure = getClosure();
console.log(closure()); // 'variable 1'
上記で定義したgetClosure()は関数を返し、返された関数はgetClosure()の内部で宣言された変数textを参照します.このように参照される変数は、関数の実行が終了したために消えるのではなく、正しい値を返します.
この戻り関数はCloserです.
エンクロージャによる非表示
通常、JavaScriptでは、オブジェクト向けプログラミングとは、Prototypeによってオブジェクトを処理することを意味する.Proptotypeでオブジェクトを作成する場合、重要な問題は、専用変数へのアクセス権の問題です.
Prototype
JavaScriptはオブジェクト向け言語であるがクラスの概念は存在しない.逆に、原型というものが存在します.
(最近のECMA 6規格では、Class構文が追加されています.ただし、構文が追加されており、JavaScriptがクラスベースになったわけではありません.)
クラスがないので、基本的に機能を継承していません.だから一般的には原型をベースに模倣継承を実現している.
(ブログ参照)
function Hello(name) {
  this._name = name;
}

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

var hello1 = new Hello('승민');
var hello2 = new Hello('현섭');
var hello3 = new Hello('유근');

hello1.say(); // 'Hello, 승민'
hello2.say(); // 'Hello, 현섭'
hello3.say(); // 'Hello, 유근'
hello1._name = 'anonymous';
hello1.say(); // 'Hello, anonymous'
上記のHello()によって生成されたオブジェクトは、_nameという変数を有する.変数名の前にUnderScore(_)が含まれているため、一般的なJavaScript命名規則を考慮すると、この変数がPrivate変数として使用したい意図が分かる.しかし、外部でも変数に近づきやすい.
したがって、モジュールを使用すると、変数への外部からの直接アクセスを制限できます.
function hello(name) {
  var _name = name;
  return function() {
    console.log('Hello, ' + _name);
  };
}

var hello1 = hello('승민');
var hello2 = hello('현섭');
var hello3 = hello('유근');

hello1(); // 'Hello, 승민'
hello2(); // 'Hello, 현섭'
hello3(); // 'Hello, 유근'
これにより、外部は_nameに近づくことができない.
反復文モジュール
var i;
for (i = 0; i < 10; i++) {
  setTimeout(function() {
    console.log(i);
  }, 100);
}
以上のコードは10万列の出力結果を生成します.どうしてですか.
パラメータをsetTimeout()に渡す匿名関数は、0.1秒後に呼び出される.0.1秒以内にfor문巡回し,iの値は10となった.したがって、匿名関数が呼び出されると、既に10のiが参照される.
この場合でも、エンクロージャを使用してオンデマンドで動作させることができます.
var i;
for (i = 0; i < 10; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(j);
    }, 100);
  })(i);
}
上のコードの間にIIFE(即時実行関数表示)が追加され,setTimeout()の匿名関数をモジュール化した.iはIIFE内にjとして注入され、エンクロージャによって異なる環境に含まれる.
繰り返し文を10回繰り返すと,10個の環境が生成され,10個の異なる環境では10個の異なるjが生成される.
この部分は理論的には理解できますが、コードを見るとあまり理解できません.
エンクロージャのパフォーマンス
エンクロージャには独自の環境があり、この環境を覚えるためにメモリを消費する必要があります.したがって、モジュールを使用した後は、参照を削除することが望ましい.
function hello(name) {
  var _name = name;
  return function() {
    console.log('Hello, ' + _name);
  };
}

var hello1 = hello('승민');
var hello2 = hello('현섭');
var hello3 = hello('유근');

hello1(); // 'Hello, 승민'
hello2(); // 'Hello, 현섭'
hello3(); // 'Hello, 유근'

// 여기서 메모리를 release 시키기 클로저의 참조를 제거해야 한다.
hello1 = null;
hello2 = null;
hello3 = null;
💡 サマリ
JavaScriptは、関数に別の関数を宣言できます.
Closerとは、内部関数が外部関数にアクセスできる脈絡のことです.すなわち,内部関数は外部関数の領域変数にアクセスでき,外部関数が消失しても内部関数は外部関数の変数にアクセスできる.
外部関数を用いた領域変数の内部関数が消失するまで外部関数は消失しないと考えられる.
これにより、エンクロージャはそれぞれの環境を記憶するためにメモリを消費する必要があります.したがって、モジュールを使用した後は、参照を削除することが望ましい.
エンクロージャは主に情報の非表示とパッケージングに使用されます.
モジュールは,関数を構成するコードと,関数を生成する際のスキャン環境からなる.したがって、関数が作成されたときのすべての変数を覚え、関数が呼び出されたときに使用できます.また、このスキャン範囲内で宣言された変数については、そのスキャン範囲外ではアクセスできないため、カプセル化することができる.
キャビネットは、閉じたスキャナーから外部に情報を提供する唯一の手段です.Closer関数内でリターンする必要があります.
アクセス制御
ゾーン変数保護
データの保存と使用