Javascriptクロージャの定義によると:
「クロージャ」は、自由変数とそれらの変数をバインドする(式を「閉じる」)環境を持つことができる式(通常は関数)です。
誰かが私に自由変数の概念を説明できますか?この概念はJavascript固有ですか、それとも他の言語にも適用されますか?
自由変数は、ローカルで宣言されておらず、パラメーターとして渡されていない変数です。
コンピュータプログラミングでは、自由変数という用語は、ローカル変数でもその関数のパラメータでもない関数で使用される変数を指します。 1 非ローカル変数という用語は、この文脈ではしばしば同義語です。
Javascriptクロージャでは、これらは、クロージャが宣言されている囲んでいるスコープまたは親スコープで関数が受け取る(読み取りと書き込み)変数です。
この実世界の例を見てください:
Gol.prototype._ensureInit = function() {
...
var _this = this;
var setDim = function() {
_this.w = _this.canvas.clientWidth;
_this.h = _this.canvas.clientHeight;
_this.canvas.width = _this.w;
_this.canvas.height = _this.h;
_this.dimChanged = true;
_this.draw();
};
setDim();
window.addEventListener('resize', setDim);
...
};
この例では、クロージャはsetDim
関数から、囲んでいるスコープで宣言された変数_this
(_ensureInit
関数)を指しています。この変数はsetDim
で宣言されておらず、渡されていません。それは「自由変数」です。
_this
は関数setDim
の変数にはならないことに注意してください。同じスコープで宣言された別の関数は、同じ変数を共有します。
「無料翻訳」は次のようになります:"out of scope" - variables
。
ECMAscriptは字句スコープを使用するため、自由変数は親スコープで定義された変数であり、スコープチェーン検索によって検索されます。
(function _outerScope() {
var foo = 42;
(function _innerScope() {
var bar = 100;
console.log( foo + bar ); // 142
}());
}());
上記の例では、foo
は_innerScope
のコンテキスト内の自由変数です。 ECMAscriptの基礎となる概念を一目見れば、非常に明白になります。
ContextはActivation Object(ES3の場合)にリンクされ、それぞれLexical Enviroment Record(ES5の場合)にリンクされています。これには次のようなものが含まれます:function declarations
、variables declared with var
とformal paramters
、およびすべてへの参照親アクティベーションオブジェクト/字句環境。変数にアクセスする必要がある場合、ECMAscriptエンジンは最初に現在のContext自体からAOs/LEsを調べます。そこに見つからない場合は、親を調べます[〜#〜] ao [〜#〜] 's/[〜#〜] le [〜#〜]の。
Contextはこのデータを配列のような構造に格納するため(Javascript自体ではなく、ここで実装レベルについて話していることを忘れないでください)、Lexical Scope
について話している、すべての親を検索するためContexts順番に。