web-dev-qa-db-ja.com

自由変数とは何ですか?

Javascriptクロージャの定義によると:

「クロージャ」は、自由変数とそれらの変数をバインドする(式を「閉じる」)環境を持つことができる式(通常は関数)です。

誰かが私に自由変数の概念を説明できますか?この概念はJavascript固有ですか、それとも他の言語にも適用されますか?

25
Geek

自由変数は、ローカルで宣言されておらず、パラメーターとして渡されていない変数です。

出典:

コンピュータプログラミングでは、自由変数という用語は、ローカル変数でもその関数のパラメータでもない関数で使用される変数を指します。 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の変数にはならないことに注意してください。同じスコープで宣言された別の関数は、同じ変数を共有します。

29
Denys Séguret

「無料翻訳」は次のようになります:"out of scope" - variables

ECMAscriptは字句スコープを使用するため、自由変数は親スコープで定義された変数であり、スコープチェーン検索によって検索されます。

(function _outerScope() {
    var foo = 42;

    (function _innerScope() {
        var bar = 100;

        console.log( foo + bar ); // 142
    }());
}());

上記の例では、foo_innerScopeのコンテキスト内の自由変数です。 ECMAscriptの基礎となる概念を一目見れば、非常に明白になります。

ContextActivation Object(ES3の場合)にリンクされ、それぞれLexical Enviroment Record(ES5の場合)にリンクされています。これには次のようなものが含まれます:function declarationsvariables declared with varformal paramters、およびすべてへの参照親アクティベーションオブジェクト/字句環境。変数にアクセスする必要がある場合、ECMAscriptエンジンは最初に現在のContext自体からAOs/LEsを調べます。そこに見つからない場合は、親を調べます[〜#〜] ao [〜#〜] 's/[〜#〜] le [〜#〜]の。

Contextはこのデータを配列のような構造に格納するため(Javascript自体ではなく、ここで実装レベルについて話していることを忘れないでください)、Lexical Scopeについて話している、すべての親を検索するためContexts順番に。

2
jAndy