1
var Gadget = function () {
    // static variable/property
    var counter = 0;
    // returning the new implementation
    // of the constructor
    return function () {
        console.log(counter += 1);
    };
}(); // execute immediately

var g1 = new Gadget(); // logs 1
var g2 = new Gadget(); // logs 2
var g3 = new Gadget(); // logs 3

このコードをデバッグすると、var counter = 0;は実行されません。new Gadget()出力は1,2,3です。

var Gadget = function () {
    // static variable/property
    var counter = 0;
    // returning the new implementation
    // of the constructor
    return function () {
        console.log(counter += 1);
    }();
}; // execute immediately

var g1 = new Gadget(); // logs 1
var g2 = new Gadget(); // logs 2
var g3 = new Gadget(); // logs 3

このコードをデバッグすると、var counter = 0;が実行されnew Gadget()、出力はになり1,1,1ます。

このデモコードはjavascriptパターン、プライベート静的メンバーです。私はこれを理解するのに少し苦労しています。

4

2 に答える 2

2

何が起こっているのかこれです。

最初のものでは、関数の終わりに()があるので、関数が実行され、returnステートメントが「varGadget」に格納されます。returnステートメントはあなたが持っているコンストラクターです-関数。つまり、新しいGadget()を実行すると、その関数が実行されます。IEでは、counter = 0を設定して外部関数をすぐに実行し、次に内部関数を変数Gadgetに返し、実行するたびにcounterをインクリメントします。

ただし、2番目の関数では、「outer」関数を「var Gadget」に格納しますが、その関数内で、inner関数を実行します。したがって、新しいガジェットを作成すると、カウンターがゼロに設定され、その後に()があるため、return関数が宣言されて実行されます。したがって、0に設定されたばかりのインクリメントカウンターが1になります。

これが理にかなっていることを願っています。関数を定義してvarに格納する場合、関数はまだ実行されていません。。などの変数を「実行」すると実行されますvar()。ただし、その後に()がある場合は、関数として実行され、RETURNSが返されるものはすべてvarに格納されます。

実際、最初のコードでは、g1、g2、およびg3はすべて同じ内部関数への参照になり、2番目のコードでは、g1、g2、およびg3は、予想どおり、ガジェット関数への参照になります。内部関数は評価し、何も返しません。

于 2012-04-29T07:58:56.840 に答える
0

最初のケースでは、変数に設定されている別の関数(内部クロージャー)を返す関数式をすぐに呼び出し、Gadgetその後new Gadget() その関数を呼び出すと、コンストラクターであるかのように呼び出されます。

Gadgetこれは、Chromeコンソールでの最初のバージョンを評価していることがわかります。

> Gadget
function () {
    console.log(counter += 1);
}

この関数は、外部(即時呼び出し)関数にバインドされたクロージャであるため、変数Gadgetの同じインスタンスを共有します。counter

于 2012-04-29T07:59:55.830 に答える