Javascriptのクローズドを理解する
4528 ワード
クローズドはECMAScriptの重要な特徴ですが、適切な定義で説明するのは難しいです.クローズドは明確には説明しにくいですが、簡単に作成できます.あるいは、不注意で作成します.しかし、クローズドの存在には、ある潜在的な問題がある.「不注意」を避けるためにクローズドを作成し、クローズドの利点をよりよく利用するためには、クローズドのメカニズムを理解する必要があります.
パッケージの定義
クローズドについては、定義が多すぎて、特に非常に抽象的な定義があります.
A"closure"is an expressition(typically a function)that can have free variables together with an environment that binds those variables.
クローズドは、いくつかの自由変数と結合されたこれらの変数の実行環境を持つ式です.このような定義は書面化しすぎて、かえって理解しにくいです.
もう一つの定義があります.
すべての関数はクローズドです.この定義は私に大きな迷いを与えました.つまり、Javascriptはブロックレベルの機能領域がないので、クローズドとは関数を指します.
ここでは関数とクローズドの関係をあまり議論したくないです.分かりやすいと思う定義を教えてください.
まず、閉込めの存在は、作用ドメインチェーンに基づいている.作用するドメインチェーンのメカニズムのために、すべての関数(大域関数でも)はコンテキストを参照して環境内の変数(すなわちfree variables)を実行することができます.
第二に、クローズド内部にfree variablesがある必要があります.ちなみに、2つの変数1.Local variables(bound variables)2.Non-local variables(free variables)
最後に、コンテキスト環境が終了した後も存在します.すなわち内部関数は、その外部関数よりも長いライフサイクルを持つ.
クローズド定義についての解析
閉包定義の2点については、同時に満足しなければならないのではないかと考えています.
まず、クローズド内部にfree variablesがないということは、外部にアクセスする変数がないということです.(他のクローズドで行動を変えない限り)フリーバリアフリーは必要条件だと思います.
第二に、関数内部にfree variablesが存在する場合、コンテキスト環境が破壊された後、それも破壊されます.内部関数は、その外部関数変数にアクセスしたが、外部関数が実行された後も回収されると考えられます.このような状況では、クローズドの議論も意味がない.
二つの例を見てみます.
クローズド・パケットの利点は、それらの外部関数を定義するパラメータと変数(thisとargmentsを除く)に内部がアクセスできることである.
クローズドバックの主な問題は、その関数を含む作用領域を保存するので、一般関数よりも多くのメモリ空間を占有するので、クローズドを過度に使用するべきではない.
クローズドの応用
クローズド・パケットの最も基本的なアプリケーションシーンは、内部変数を保護することによって、モジュール・モードなどのプライベートを実現することである.
パッケージの定義
クローズドについては、定義が多すぎて、特に非常に抽象的な定義があります.
A"closure"is an expressition(typically a function)that can have free variables together with an environment that binds those variables.
クローズドは、いくつかの自由変数と結合されたこれらの変数の実行環境を持つ式です.このような定義は書面化しすぎて、かえって理解しにくいです.
もう一つの定義があります.
すべての関数はクローズドです.この定義は私に大きな迷いを与えました.つまり、Javascriptはブロックレベルの機能領域がないので、クローズドとは関数を指します.
ここでは関数とクローズドの関係をあまり議論したくないです.分かりやすいと思う定義を教えてください.
まず、閉込めの存在は、作用ドメインチェーンに基づいている.作用するドメインチェーンのメカニズムのために、すべての関数(大域関数でも)はコンテキストを参照して環境内の変数(すなわちfree variables)を実行することができます.
第二に、クローズド内部にfree variablesがある必要があります.ちなみに、2つの変数1.Local variables(bound variables)2.Non-local variables(free variables)
最後に、コンテキスト環境が終了した後も存在します.すなわち内部関数は、その外部関数よりも長いライフサイクルを持つ.
クローズド定義についての解析
閉包定義の2点については、同時に満足しなければならないのではないかと考えています.
まず、クローズド内部にfree variablesがないということは、外部にアクセスする変数がないということです.(他のクローズドで行動を変えない限り)フリーバリアフリーは必要条件だと思います.
第二に、関数内部にfree variablesが存在する場合、コンテキスト環境が破壊された後、それも破壊されます.内部関数は、その外部関数変数にアクセスしたが、外部関数が実行された後も回収されると考えられます.このような状況では、クローズドの議論も意味がない.
二つの例を見てみます.
var objectA = (function() { var localA = "localA"; innerFn(); //
function innerFn() { localA = "innerChange"; } return { getLocalA : function() { return "empty"; } }; })(); objectA.getLocalA(); objectA.getLocalA = function() { return localA; }; //console.log(objectA.getLocalA()); //error: localA is not defined
var objectB = (function() { var localB = "localB"; return { getLocalB : function() { return "empty"; }, updateGetLocalB : function() { this.getLocalB = function() { return localB; }; }, updateLocalB : function() { localB = "changeLocalB"; } }; })(); console.log(objectB.getLocalB()); // empty
//
objectB.updateGetLocalB(); console.log(objectB.getLocalB()); // localB
objectB.updateLocalB(); console.log(objectB.getLocalB()); // changeLocalB
クローズドの長所と短所クローズド・パケットの利点は、それらの外部関数を定義するパラメータと変数(thisとargmentsを除く)に内部がアクセスできることである.
クローズドバックの主な問題は、その関数を含む作用領域を保存するので、一般関数よりも多くのメモリ空間を占有するので、クローズドを過度に使用するべきではない.
クローズドの応用
クローズド・パケットの最も基本的なアプリケーションシーンは、内部変数を保護することによって、モジュール・モードなどのプライベートを実現することである.