2012-08-14 8 views
5

Nach meiner letzten Frage, das ist eine genauere für mich:„var“ Variablen „diese“ Variablen und „global“ Variablen - in einem JavaScript-Konstruktor

Beispiel:

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

, was ich jetzt verstehen:

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. 

Verstehe ich richtig?

Auch - wenn ich var blabla = 10; und die getblabla Funktion, die es in der Auftragnehmer verwendet, dann wird für jede Instanz von Foo ("foo" ...), wird eine Foo Auftragnehmer Funktion in den Speicher, der dies enthält gespeichert "private" Variable. oder wird es die gleiche Foo-Funktion als Platz für die privaten Variablen sein - für ALLE Instanzen (wie "foo") von Foo?

+0

Ihre ersten drei Aussagen sind korrekt. Ich folge nicht ganz dem, was du für deine letzte Frage bittest. Könntest Du das erläutern?Kannst du auch Variablen ausprobieren, die nicht so ähnlich benannt sind? Es ist schwer zu folgen. Vielen Dank. – Brad

+0

Es ist auch kompliziert für mich. Ich meine - das ist eine Schließung, oder? und es ist ein Auftragnehmer - also wird für jede Instanz von Foo eine neue Schließung von Foo in der Erinnerung sein? Wie funktioniert das Zeug? Vielen Dank. – Daniel

Antwort

6

einfach auf dem Rahmen zu konzentrieren, ich durch dieses Beispiel laufen werde, (mit klaren Variablen) Danach verbinde ich es wieder mit deinen Variablen.

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" 

Die Linie: this.x entspricht this.bla und definiert eine extern verfügbaren Attribut eines Foo Objekts. y ist äquivalent zu blablabla=100 und dann die x innerhalb foo ist äquivalent zu Ihrem blablabla innerhalb foo. Hier ist eine wirklich grobe jsfiddle Sie können laufen, um dies zu sehen.

1

Ja, Sie verstehen es!
Wie beim zweiten Teil der Frage geht es um die Vererbung, genau wie die Beziehung zwischen dem (globalen) Fenster und den Funktionen, die in seinem Bereich definiert sind (denke root). Also alles, was du nicht neu spezifizierst, wird nach dem Vorfahren gesucht.

Dies ist ein tremendous good video von Crockford, der es wirklich gut erklärt.

2

Alles, was Sie gesagt haben, ist korrekt. (Natürlich wird ein Fehler bei der blablabla Zuweisung in Strict Mode.

geworfen. Auf der zweiten Hälfte gibt es nichts besonderes an der Konstruktorfunktion. Es funktioniert nur wie jede andere Funktion in dem es eine Schließung schafft, die so lange besteht . als verwiesen (die Lebensdauer von this.getblabla in diesem Fall)

Nehmen Sie dieses Beispiel:

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(); 

Hier ist der Foo Konstruktor keinen Verschluss und ihr Umfang wird sofort freigegeben bildet initBlaBla auf der anderen Seite. Han d schafft eine Schließung. Interessanterweise kann der Compiler sehen, dass blabla niemals in this.getblabla geschrieben und optimiert wird, um immer 10 zurückzugeben und niemals den Abschlussbereich zu speichern. Dies wird angezeigt, wenn Sie die Ausführung in einer Funktion innerhalb eines Closings unterbrechen und versuchen, einen Wert zu lesen, auf den intern nicht verwiesen wird.

Der Umfang Schließung wird für die Garbage Collection erhält freigegeben und in der Warteschlange, wenn Sie eines der folgenden nennen:

delete foo.getblabla; 
foo.getblabla = "Anything!"; 
foo = "Anything else.";