2012-08-14 18 views
5

po moim ostatnim pytaniu, ten jest bardziej dokładna dla mnie:„zmienna” zmienne „to” zmienne i „globalne” zmienne - Wewnątrz JavaScript Konstruktora

przykład:

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

co ja teraz rozumiem:

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. 

Czy rozumiem poprawnie?

Również - jeśli uwzględnię funkcję var blabla = 10; i getblabla, która używa jej w kontrahenta, to dla każdej instancji Foo ("foo" ...) zostanie zapisana funkcja kontrahenta Foo w pamięci, która obejmuje to "prywatna" zmienna. czy będzie to ta sama funkcja Foo co miejsce dla prywatnych zmiennych - dla instancji (takich jak "foo") z Foo?

+0

Twoje pierwsze trzy twierdzenia są poprawne. Nie podążam całkowicie za tym, o co pytasz na ostatnie pytanie. Możesz wyjaśnić?Czy możesz też wypróbować zmienne, które nie są tak nazwane? Trudno jest naśladować. Dzięki. – Brad

+0

To też jest dla mnie skomplikowane. Mam na myśli - to zamknięcie, prawda? i jest to wykonawca - więc na każde wystąpienie Foo pojawi się nowe zamknięcie Foo w pamięci? jak to działa? dzięki. – Daniel

Odpowiedz

6

Wystarczy skoncentrować się na zakresie, idę do pracy przez ten przykład (z jaśniejsze zmienne) Później połączę go z twoimi zmiennymi.

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" 

linii: this.x odpowiada this.bla oraz określa zewnętrznie dostępne atrybut Foo obiektu. y jest odpowiednikiem blablabla=100, a następnie x w foo jest równoważne twojemu blablabla w foo. Oto naprawdę ostry jsfiddle, który możesz uruchomić, aby to zobaczyć.

1

Tak, rozumiesz!
Jeśli chodzi o drugą część pytania, chodzi o dziedziczenie, podobnie jak relacja między oknem (globalnym) a funkcjami zdefiniowanymi w jego zasięgu (myśl root). Więc wszystko, czego nie określisz ponownie, zostanie sprawdzone u przodka.

To jest tremendous good video autorstwa Crockford, który wyjaśnia to NAPRAWDĘ dobrze.

2

Wszystko, co powiedziałeś, jest poprawne. (Oczywiście, błąd zostanie rzucony na przypisanie blablabla w Strict Mode.

W drugiej połowie, nie ma nic szczególnego w funkcji konstruktora. To po prostu działa jak każdej innej funkcji w tym, że tworzy zamknięcie, które utrzymuje się tak długo, . jako jego odwołania (trwania this.getblabla w tym przypadku)

Weźmy ten przykład:

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

Tutaj konstruktor Foo nie tworzy zamknięcie i jego zakres zostanie wydana niezwłocznie initBlaBla z drugiej strony. han d tworzy zamknięcie. Co ciekawe, kompilator może zauważyć, że blabla nigdy nie jest zapisywana i optymalizowana, aby zawsze zwracać 10 i nigdy nie zapisywać zakresu zamknięcia. Można to zobaczyć, gdy przerwiesz wykonywanie w funkcji wewnątrz zamknięcia i spróbujesz odczytać wartość, której nie odwołuje się wewnętrznie.

Zakres zamknięcie dostanie zwolniony, a w kolejce do zbierania śmieci, jeśli nazwać jedną z następujących czynności:

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