クロージャは ECMAScript の非常に重要な機能ですが、適切な定義で記述するのは困難です。クロージャは明確に説明するのが難しいですが、簡単に作成できたり、誤って作成されたりすることがあります。ただし、クロージャの存在には実際には特定の潜在的な問題があります。 「誤って」クロージャが作成されることを避け、その利点をよりよく活用するには、クロージャの仕組みを理解する必要があります。
クロージャーの定義
クロージャーに関しては、定義が多すぎます。特に、次のような非常に抽象的な定義もあります。
A "closure" " は、自由変数とそれらの変数をバインドする環境を持つことができる式 (通常は関数) です。
大まかに言えば、クロージャはいくつかの自由変数を持ち、これらの変数の実行環境をバインドする式です。この定義は文字通りすぎて理解するのが困難です。
別の定義があります:
すべての関数はクロージャです。この定義は私を非常に混乱させます。つまり、JavaScript にはブロックレベルのスコープがないため、クロージャは一般的に関数を指します (関数以外にクロージャを形成する方法は思いつきません)。
ここでは関数とクロージャの関係についてはあまり議論したくありません。理解しやすいと思われる定義を示しましょう。
まず第一に、クロージャの存在はスコープチェーンに基づいています。スコープ チェーン メカニズムにより、すべての関数 (グローバル関数も含む) はコンテキスト実行環境内の変数 (つまり、自由変数) を参照できます。
次に、クロージャ内に自由変数が存在する必要があります。ちなみに、変数には 2 種類あります 1. ローカル変数 (束縛変数) 2. 非ローカル変数 (自由変数)
最後に、コンテキストが終了した後も存在します。つまり、内部関数のライフサイクルは外部関数よりも長くなります。
クロージャ定義の解析について
クロージャ定義の2点について、同時に満たさなければならないか検討してきました。
まず、クロージャ内に自由変数がない場合、つまり外部変数にアクセスしない場合、クロージャの意味は失われます。 (他のクロージャによって動作が変更されない限り) したがって、自由変数は必須だと思います。
次に、関数内に自由変数がある場合、そのコンテキストが破棄されると、その変数も破棄されます。内部関数はその外部関数の変数にアクセスしますが、外部関数の実行後にもリサイクルされることが想像できます。この場合、クロージャについての議論は無意味です。
2 つの例を見てみましょう:
闭包の利点と欠点
パケットの主な利点は、外部関数を定義するパラメータと量を (this と引数を除いて) 内部で保持できることです。したがって、一般的な関数よりも多くの内部ストレージ空間が占有されるため、あまりパケットを使用することはできません。
ブロックの最も基本的なアプリケーションは、モジュール モードのように、内部の変化を保護することによって実現されます。