2012-06-10 18 views
9

Przeczytałem, że tworzenie przestrzeni nazw dla projektów JavaScript pomaga w zmniejszeniu konfliktów z innymi bibliotekami. Mam pewien kod z wieloma różnymi typami obiektów, dla których zdefiniowałem funkcje konstruktora. Czy dobrą praktyką jest umieszczanie ich w przestrzeni nazw?Konstruktorzy wewnątrz przestrzeni nazw

Na przykład:

var shapes = { 
    Rectangle: function(w, h) { 
     this.width = w; 
     this.height = h; 
    } 
}; 

która może być wywołana przez:

var square = new shapes.Rectangle(10,10); 
+3

moim zdaniem jest dobrym pomysłem –

+0

konstruktora, który jest funkcją, staje się * wyrażeniem funkcji * zamiast deklaracji funkcji * jeśli przypisujesz ją do właściwości obiektu w "przestrzeni nazw" zamiast po prostu wpisujesz 'function Rectangle (w, h) {}. Ma to niewielkie różnice: https: //developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions Poza tym nie zanieczyszcza globalnej przestrzeni nazw, co jest dobre, jak zauważyli inni. – caw

Odpowiedz

4

Ten obszar nazw nazywa się "Singleton pattern" i jest to jeden z głównych wzorów zalecanych przez słynną książkę o wzorach "Gang of Four".

Od wielkiego (i za darmo) książki Learning JavaScript Design Patterns:

Klasycznie, wzorzec Singleton może być realizowane poprzez stworzenie klasy z metody, która tworzy nową instancję klasy, jeśli nie jeden istnieć. W przypadku istniejącej instancji po prostu zwraca odniesienie do tego obiektu. Wzorzec Singleton jest zatem znany jako , ponieważ ogranicza instancję klasy do pojedynczego obiektu.

W języku JavaScript, single występują jako dostawca przestrzeni nazw, który izoluje kod implementacji z globalnej przestrzeni nazw, aby zapewnić pojedynczy punkt dostępu dla funkcji.

Mogą wziąć w wielu różnych formach, ale w jej najbardziej podstawowego, Singleton mogą być realizowane jako obiekt dosłownym grupowane z powiązanych z nim funkcji i właściwości ...

Więc tak Jest to dobrze stosowana koncepcja w wielu językach programowania i doskonale nadaje się do zapobiegania kolizjom obiektów globalnej przestrzeni nazw w JavaScript.

Zobacz także: Simplest/Cleanest way to implement singleton in JavaScript?

+1

Świetnie. Wielkie dzięki. Dziękuję również za linki. Po prostu nie widziałem żadnego przykładu nazywania "nowego" funkcją w przestrzeni nazw i zastanawiałem się, czy istnieje ku temu powód. – Joe

+0

Nie ma powodu, dla którego mógłbym myśleć. Nowa funkcja to prototypowe dziedziczenie JavaScriptu, które jest często używane w praktyce jako dziedziczenie przypominające klasę. Większość przykładów, które zobaczysz, definiuje tylko jedną "klasę", ale jeśli próbujesz zorganizować ich grupę, wzorzec singletonu jest równie dobry, jeśli nie bardziej użyteczny. – buley

+2

@joe oczywiście nie jest to wzorzec singletowy, jeśli literał obiektu zawiera konstruktory ;-) –

2

Tak. Powinieneś zanieczyszczać globalną przestrzeń nazw możliwie najmniejszą

2

Tak, to dobry pomysł, ponieważ pozwala uniknąć kłopotów i zamieszania spowodowanego przez zanieczyszczanie globalnej przestrzeni nazw. Chociaż osobiście zmieniłbym shapes na shape, więc mógłbyś wtedy mieć shape.Rectangle, co ma dla mnie trochę więcej sensu (w końcu Prostokąt jest tylko jednym obiektem).

1

Poza tym nie zanieczyszczają przestrzeń nazw, ale również pozwala zrobić sprawdzanie typu family:

function doSomethingTo(shape) { 
    var shapeName, validArg; 

    for (shapeName in shapes) { 
    validArg = validArg || shape instanceof shapes[shapeName]; 
    } 

    if (!validArg) throw "Argument is not a shape."; 
} 
5

ogół jest to dobry pomysł; Ponadto, jeśli obiekty wymagają zestaw funkcji wspólnych, które nie powinny być narażone można owinąć je wszystkie wewnątrz zamknięcia, podobnie jak moduł:

var shapes = (function() { 
    // private variables 
    var foo = 0; 

    // private function 
    function get_area(w, h) 
    { 
    return w * h; 
    } 

    return { 
    Rectangle: function(w, h) { 
     this.width = w; 
     this.height = h; 
     // call private function to determine area (contrived example) 
     this.area = get_area(w, h); 
    } 
    } 
}()); 

var s = new shapes.Rectangle(100, 5); 
Powiązane problemy