ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript クロージャ - クロージャの範囲

JavaScript クロージャ - クロージャの範囲

黄舟
黄舟オリジナル
2017-01-20 14:17:251167ブラウズ

クロージャは JavaScript において非常に重要な概念です。クロージャとは、上位レベルの関数またはスコープから取得した変数 (キーと値のペア) のコピーが別のスコープに保存されることを意味します。これらのキーと値のペアは、上位レベルの関数の実行が完了してもクローズされません。 。 破壊されました。クロージャは基本的に、オブジェクトのメンバー プロパティがいつ GC (ガベージ コレクション メカニズム) によって処理されるかを説明します。

実際に、前の関数の値の転送でクロージャに遭遇しました。関数の値の転送を説明するときに、オブジェクトのプロパティを比較する関数 sortByProperty をリストしました。この関数の戻り値は匿名関数であり、実際にはクロージャです。クロージャの範囲を説明するために、引き続きこの例を使用します。この関数のコードは次のように少し変更されています:

// 比较对象属性大小的通用函数
function compareObjectFunction(prop){
  //匿名函数
  return function(obj1,obj2){
    if(obj1[prop] > obj2[prop]) return 1;
    else if(obj1[prop] < obj2[prop]) return -1;
    else return 0;
  }
}
// 创建2个对象
var o1 = {name:"Leon",age:22}
var o2 = {name:"Ada",age:25}
// 比较对象的name属性
var compare = compareObjectFunction("name");
// 返回值
var returnValue = compare(o1,o2);
console.info(rel);  //比较name属性会返回1,比较age属性会返回-1

上の例では、クロージャを使用する最大の利点は、compareObjectFunction のスコープが大きくなったことです。compareObjectFunction 関数が終了しても、prop 変数はまだ存在します。

JavaやC++などの静的オブジェクト指向プログラミング言語では、var Compare = CompareObjectFunction("name")という文を実行した後、メモリが解放され、prop属性がガベージコレクションされます。ただし、JavaScript では、コードが var rel = Compare(o1,o2); として実行された場合でも、関数を返すことによって関数のスコープを拡張するこの方法は prop 属性にアクセスできます。

注意すべき点が 1 つあります。クロージャーは匿名関数と同等ではありません。クロージャを作成する方法は通常、別の関数の中に関数を作成することによって行われます。では、クロージャはどのようにして関数の範囲を拡大するのでしょうか?この問題を説明するために、関数の実行時にスコープ メモリ モデルを引き続き使用します。

まず、compareObjectFunction 関数を作成し、次に 2 つのオブジェクト o1 と o2 を作成しました。これらのコードを完了すると、メモリ内のスコープ チェーン モデルは次のようになります:

JavaScript クロージャ - クロージャの範囲

CompareObjectFunction のスコープ チェーンの上位ビットは、グローバル スコープ。下位ビットは独自のスコープを指します。現時点では、グローバル スコープには 3 つの変数があります。

次に、オブジェクトの name 属性の比較を開始し、次のコードを実行します:

var compare = compareObjectFunction("name");
var returnValue = compare(o1,o2);

name をパラメータとして CompareObjectFunction 関数に渡して、2 つのオブジェクトの名前のサイズを比較します。上記の 2 行のコードを実行した後のスコープ チェーンのメモリ モデルは次のようになります。

JavaScript クロージャ - クロージャの範囲

compareObjectFunction 関数が実行されると、匿名関数が返され、匿名関数にもスコープ チェーンがあります。その上位ビットはグローバル スコープを指し、中位ビットはそのcompareObjectFunctionを含むスコープを指し、下位ビットはそれ自体のスコープを指します。

プログラムが CompareObjectFunction("name") コードを実行した後、compareObjectFunction 関数は実行を完了し、GC がその関数のリサイクルを開始します。ただし、GC は、compareObjectFunction のスコープを指している別の匿名関数があることを検出します。この時点では、GC はこのスコープのメモリを再利用しません。 CompareObjectFunction のスコープ チェーンと関数自体のメモリは、GC によってガベージ コレクションされます。

プログラムがcompare(o1,o2)を実行すると、まず独自のスコープ内でobj1とobj2の値をそれぞれo1とo2に変更します。次に、独自のスコープ空間内にあるため、prop属性を呼び出す必要があります。この属性がスコープ内に見つからない場合は、リンク リストの上位レベルが指す CompareObjectFunction スコープ内で検索します。このとき、prop 属性が name であることがわかり、name 属性を使用して比較します。戻り値を取得します。

匿名関数が CompareObjectFunction のスコープを指しているため、compareObjectFunction 関数の実行後、そのスコープ空間が GC によってガベージ コレクションされず、したがって prop 属性のスコープが拡大されることがわかります。

JavaScript クロージャは関数のスコープを拡大できますが、その代償として、プログラムの実行時により多くのメモリ領域を占有することになるため、クロージャを悪用することはできず、必要な場合にのみ使用します。

上記は JavaScript のクロージャ - クロージャ スコープの内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。