5

私の最後の質問の後、これは私にとってより正確です:

例:

function Foo() {
    this.bla = 1;
    var blabla = 10;
    blablabla = 100;
    this.getblabla = function () { 
        return blabla; // exposes blabla outside
    }
}
foo = new Foo();

私が今理解していること:

this.bla = 1;     // will become an attribute of every instance of FOO.
var blabla = 10;  // will become a local variable of Foo(will **not** become an attribute of every instance of FOO), which could be accessed by any instance of FOO - only if there's a method like "this.getBlabla". that's a "closer" ?
blablabla = 100;  // will define a **new** (or change if exist) global(window) variable.

正しく理解できますか?

また、請負業者にそれを使用する関数を含めるvar blabla = 10;と、 Foo( "foo" ...)のすべてのインスタンスについて、この"private"変数を含むFoo請負業者関数がメモリに保存されます。getblablaまたは、プライベート変数の場所と同じFoo関数になりますか?Fooのすべてのインスタンス(「foo」など)の場合ですか?

4

3 に答える 3

7

スコープに焦点を当てるために、この例を実行します(より明確な変数を使用)。その後、変数を変数に接続し直します。

var x = "Global scope";
var y = "Not changed.";

function Foo() {
    this.x = "Attribute of foo";
    var x = "In foo's closure";
    y = "Changed!"
    this.getX = function () { 
        return x;
    }
}

// do some logging

console.log(x); // "Global scope"
console.log(y); // "Not changed"
foo = new Foo();
console.log(y); // "Changed!"
console.log(foo.x); // "Attribute of foo"
console.log(x); // "Global scope"
console.log(foo.getX()); // "In foo's closure"

行:this.xはと同等this.blaであり、オブジェクトの外部で使用可能な属性を定義しFooます。yはと同等でblablabla=100あり、xwithinfooはあなたのwithinfooと同等blablablaです。これは、これを確認するために実行できる非常に大まかなjsfiddleです。

于 2012-08-14T17:30:32.307 に答える
2

あなたが言ったことはすべて正しいです。(もちろん、厳密モードblablablaの割り当てではエラーがスローされます。

後半は、コンストラクター関数について特別なことは何もありません。参照されている限り(this.getblablaこの場合はの存続期間)持続するクロージャを作成するという点で、他の関数と同じように機能します。

この例を見てください:

function initBlaBla() {
    var blabla = 10;
    this.getblabla = function () { 
        return blabla; // exposes blabla outside
    }
}

function Foo() {
    this.bla = 1;
    blablabla = 100;
    initBlaBla.call(this);
}

foo = new Foo();

ここでは、Fooコンストラクターはクロージャーを形成せず、そのスコープはすぐに解放されます。 initBlaBla一方、クロージャーを作成します。興味深いことに、コンパイラーは、blablaが書き込まれることはなくthis.getblabla、常に10を返すように最適化され、クロージャースコープを保存しないことを認識している可能性があります。これは、クロージャ内の関数で実行を中断し、内部で参照されていない値を読み取ろうとしたときに見られます。

次のいずれかを呼び出すと、クロージャスコープが解放され、ガベージコレクションのキューに入れられます。

delete foo.getblabla;
foo.getblabla = "Anything!";
foo = "Anything else.";
于 2012-08-14T17:28:44.553 に答える
1

はい、あなたはそれを理解しています!
質問の2番目の部分については、(グローバル)ウィンドウとそのスコープ(ルートを考えてください)で定義された関数との関係と同じように、すべて継承に関するものです。したがって、再指定しないものはすべて、祖先で検索されます。

これはCrockfordによる非常に優れたビデオであり、彼はそれを本当によく説明しています。

于 2012-08-14T17:10:26.323 に答える