2012-08-14 17 views
5

内部の私の最後の質問の後、これは私のために、より正確である:「VAR」変数、「この」変数と「グローバル」変数 - JavaScriptのコンストラクタ

例:

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

何I今すぐ理解:

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;getblabla関数を使用すると、Foo( "foo" ...)のすべてのインスタンスに対して、これを含むFoo請負業者関数がメモリに保存されます"プライベート"変数。またはそれはプライベート変数のための場所と同じFoo関数ですか - ALL Fooのインスタンス(fooのような)?

+0

最初の3つのアサーションが正しいです。私はあなたの最後の質問をしていることに完全に従っていません。明確にすることはできますか?同様に名前が付けられていない変数を試すことができますか?それは続くことは難しい。ありがとう。 – Brad

+0

それは私にとっても複雑です。私は閉鎖を意味する、そうですか?それは請負業者だから、Fooのあらゆるインスタンスに対して、Fooの新しい閉鎖が記憶に残るだろうか?どのようにこの作品は動作しますか?ありがとう。 – Daniel

答えて

6

を、私は(明確で、この例を実行するつもりです変数)その後、変数に接続し直します。

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.xthis.blaは、に相当し、それはFoo物体の外部で利用可能な属性を定義します。 yblablabla=100に相当し、foo内のxはfoo内のblablablaに相当します。これは実際にはおおよそjsfiddleです。これを見るために実行することができます。

1

はい、わかっています!
質問の第2の部分については、(グローバル)ウィンドウとそのスコープで定義された関数(ルートと考える)との間の関係と同様に、継承に関するものです。あなたが再指定しないものはすべて、祖先を参照します。

これは本当によく説明しているCrockfordのtremendous good videoです。

2

あなたが言ったことはすべて正しいです。 (もちろん、blablabla代入でエラーが発生するStrict Mode

後半では、コンストラクタ関数に特別なものはありません。他の関数と同様に動作します。その参照される(この場合は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を。漢dはクロージャを作成します。興味深いことに、コンパイラは、blablaが決して書き込まれず、this.getblablaを常に10に戻してクローズスコープを保存しないように最適化することがあります。これは、クロージャー内の関数で実行を中断し、内部的に参照されていない値を読み込もうとするときに見られます。

閉鎖スコープでは、次のいずれかを呼び出した場合に解除され、ガベージコレクションのためにキューに入れられてしまいます:ちょうど範囲に集中する

delete foo.getblabla; 
foo.getblabla = "Anything!"; 
foo = "Anything else."; 
関連する問題