2009-11-30 14 views
10

Jestem stosunkowo nowy w JS i mam problemy poprawnie emulujące zasady OOP.Klasy JavaScript i zakres zmienny

Chyba mam dwa pytania. Pytanie pierwsze dotyczy wielu sposobów deklarowania zmiennych.

Say mam klasy:

function clazz(a) 
{ 
    this.b = 2; 
    var c = 3; 
    this.prototype.d = 4; // or clazz.prototype.d = 4? 
} 

var myClazz = new clazz(1); 

mam rację w następujących ocen:

a jest prywatna zmienna jest wystąpienie specyficznych (tj różne instancje clazz będzie miał wyjątkowe i niezależne zmienne 'za'). Dostęp do niego można uzyskać z poziomu clazz jako: "a".

b jest publiczną zmienną, która jest specyficzna dla instancji. Dostęp do niego można uzyskać od clazz jako "this.b", a od zewnętrznego clazz jako "myClazz.b".

c jest zmienną prywatną, która jest statyczna lub specyficzna dla klasy (to znaczy różne instancje clazz mają tę samą zmienną "c"). Dostęp do niego można uzyskać z dowolnego wystąpienia clazz jako "c", a zmiany w instancji clazz są odzwierciedlane we wszystkich instancjach clazz.

d jest publiczną zmienną, która jest specyficzna dla typu statycznego/klasy. Dostęp do niego można uzyskać z dowolnego miejsca za pomocą "clazz.prototype.d" lub "myClazz.prototype.d".

Ogólna kwestia, którą mam z moim zrozumieniem schematu zmiennych, polega na tym, że nie ma możliwości zadeklarowania zmiennej prywatnej, która NIE jest statyczna (tj. Unikalna wersja dla każdej instancji klasy).

Drugie pytanie dotyczy różnych typów deklaracji klas.

Używam:

var MySingleton = new function() {...}; 

do tworzenia pojedynczych. Czy to jest poprawne? Jestem też pewien, co do efektu „nowe” słowo kluczowe w tej sytuacji, a także dodanie() funkcja szelki do końca deklaracji jako tak:

var MySingleton = new function() {...}(); 

Używam tego wzoru do zadeklaruj klasę, a następnie instancję instancji tej klasy:

function myClass() {...}; 
var classA = new myClass(); 
var classB = new myClass(); 

Czy to właściwa metoda?

Odpowiedz

18

Jesteś tuż za a i b:

a jest argumentem, dostępny tylko w zakresie constructor function.

b to publiczna zmienna instancji dostępna we wszystkich instancjach utworzonych za pomocą tej funkcji konstruktora.

c to zmienna prywatna, dostępna tylko w funkcji konstruktora.

Deklaracja d jest nieważny, ponieważ obiekt prototype ma być używany tylko na constructor functions, jak Clazz.prototype.d = 3;, jeśli zrobisz to tak, zmienna zostanie udostępniony, ale można przypisać wartość na konkretnym przypadku, a domyślną wartością będzie zasłonięta (przez łańcuch prototypów).

Dla „zmienne prywatne” można użyć sposób zadeklarować c, na przykład: Metody

function Clazz(){ 
    var c = 3; // private variable 

    this.privilegedMethod = function() { 
     alert(c); 
    }; 
} 

uprzywilejowane, są publiczne, ale mogą uzyskać dostęp „prywatny” zmienne zadeklarowane wewnątrz funkcji konstruktora.

Do tworzenia pojedynczych, najprostszym sposobem jest może używać przedmiotu dosłowne, jak:

var myInstance = { 
    method1: function() { 
    // ... 
    }, 
    method2: function() { 
    // ... 
    } 
}; 

A jeśli chcesz członków prywatnych na singleton przykład, można:

var myInstance = (function() { 
    var privateVar = ''; 

    function privateMethod() { 
    // ... 
    } 

    return { // public interface 
    publicMethod1: function() { 
     // all private members are accesible here 
    }, 
    publicMethod2: function() { 
    } 
    }; 
})(); 

ten został nazwany wzorzec modułu, w zasadzie pozwala hermetyzować prywatne elementy obiektu, korzystając z funkcji closures.

Więcej informacji:

Edit: O składni dodawać posty:

var mySingleton = new (function() { 
    // ... 
})(); 

za pomocą operatora new jesteś grudnia W tym celu należy użyć anonimowej funkcji konstruktora, która wygeneruje nową instancję obiektu. Jest ona jednak ważna, ale ja osobiście wolałabym podejście do wzorca "modułowego", aby utworzyć własną instancję obiektu (i uniknąć new).

Również, czytając new function() {}, myślę, że to nie jest naprawdę intuicyjne i może powodować zamieszanie, jeśli nie rozumiesz dobrze, jak działa operator new.

O nawiasach są opcjonalne, operator new wywoła konstruktor funkcji bez parametrów, jeśli nie dodać je (zobaczyć ECMA-262, 11.2.2).

+2

+1. Bardzo kompletna i wyczerpująca odpowiedź. –

+0

Dziękuję za odpowiedź informacyjną. Dodatek: Jakie są namacalne różnice między podejściem modułowym do deklaracji singletowej a stylem wymienionym w oryginalnym wpisie? – Cmc

+0

** @ Lior: ** thanks !, ** Cmc: ** Napisałem trochę o składance, którą opublikowałeś ... – CMS

3

OK, pozwala przejść nad tym:

  1. 'a' jest argument przekazany do konstruktora klasy. Będzie istnieć tylko przez czas trwania inwokacji konstruktora. Oznacza to, że prawdopodobnie powinnaś gdzieś przechowywać swoją wartość.

  2. "b" jest członkiem instytucji publicznej. Jest to specyficzna dla instancji (mimo, że przypisujesz wartość w konstruktorze, wszystkie instancje będą początkowo miały tę samą wartość dla "b").

  3. 'c' jest prywatnym członkiem instancji. Będzie jednak dostępny tylko wewnątrz twojego konstruktora, ponieważ jest zdefiniowany tylko w tym zakresie. Jeśli nie odnosisz się do niego z zamknięcia wewnątrz funkcji konstruktora, jego los będzie podobny do "a" powyżej.

  4. "d" jest członkiem instytucji publicznej. Każda instancja twojej klasy będzie miała członka "d" z początkowo wartością 4. Należy jednak pamiętać, że przypisanie obiektu typu odniesienia do prototypowego elementu twojej klasy (takiego jak "d") spowoduje, że każdy element instancji "d" będzie odnosił się do tego samego obiektu. Przykład:

    MyClass.prototype.d = { prop1: 'val1', prop2: 'val2' };   
    var a = new MyClass(); 
    var b = new MyClass();   
    a.d.prop1 = 'foo'; // is the same as: b.d.prop1 = 'foo'; 
    
  5. Statyczne członkowie klasy są definiowane przy użyciu:

    function MyClass() 
    { 
        // ... 
    }  
    MyClass.staticMemeber = 'I am a static member'; 
    

    Powinieneś raczej nie traktują MyClass.prototype jako miejsce na organizację elementy statyczne/methods.Everything przypisanych do klas "prototyp jest z kolei członkiem każdej z jego instancji.

  6. Gdy() są dołączone do definicji funkcji (zaraz po bloku), funkcja jest wykonywana. Oznacza to:

    var myFunc = function() { alert('blah'); }(); 
    

    spowodowałoby jedynie wywołanie metody. Następujący kod:

    var MySingleton = new function() {...}(); 
    

    oznacza "użyj wartości zwracanej z funkcji() jako konstruktora dla MySingleton".