2013-04-07 15 views
8

Załóżmy, że tworzysz typ danych i ujawniasz ich zachowanie.JavaScript: jakie są wytyczne dotyczące definiowania nowych typów danych?

można podać kilka przykładów, kiedy należałoby użyć:

  • funkcję & nowy:

    // define new data type 
    var CustomDataType= function(){ 
             this.a='whatever'; 
             this.doX= function(){/*some code*/}; 
            } 
    
    // create a new instance of our custom data type 
    var obj= new customDataType(); 
    
  • obiekt dosłowne & Object.create:

    // define new data type 
    var customDataType = { 
             a: 'whatever', 
             doX: function(){/*some code*/} 
            } 
    
    // create a new instance of our custom data type 
    var obj= Object.create(customDataType); 
    
  • Funkcja, która Cię buduje R obiektu:

    function customDataTypeFactory(options){ 
        return { 
          a: 'whatever', 
          doX: function(){/*some code*/} 
         } 
    }; 
    
    // create a new instance of our custom data type 
    var obj= customDataTypeFactory(options); 
    

czuję, że to może być oznaczony duplikat dla: new vs Object.create ale moim głównym celem nie jest w dyskusji, który z nich jest lepszy, ale raczej wiedzieć, czy istnieją szczególne przypadki użycia, gdzie trzeba być preferowanym w stosunku do innych.

Przeczytałem wiele postów na podobne pytania i książkę z Crockford: JavaScript: dobre części. Do tej pory doszedłem do wniosku, że jest to kwestia preferencji, ale twarde rady od Crockford wiele mi mówią: "staram się unikać funkcji, które są niebezpieczne i niepotrzebne" ... mówię o new.

+0

Twoje pierwsze i trzecie wersje umieszczają właściwości bezpośrednio na nowym obiekcie. W drugiej wersji obiekt dziedziczy właściwości. Nie wiem, czy jest jakaś konkretna odpowiedź na twoje pytanie. Pierwszy używa konstruktora, jeśli wywołasz używając 'new', a' instanceof' będzie działać, aby zidentyfikować ten obiekt.Trzeci nie wymaga użycia 'new', ale' instanceof' nie będzie tak użyteczny. Drugi ponownie dziedziczy właściwości, więc budowanie wielu obiektów w ten sposób będzie współużytkować dane, a wszystkie obiekty będą obserwować aktualizacje odziedziczonego obiektu. –

+0

... i nie daj się zbytnio powiesić na ostrzeżeniach o niebezpieczeństwie Crockforda. Myślę, że trochę się martwi. Rozumiem, weź to wszystko, ale weź to z przymrużeniem oka. –

+1

'this.doX =' powinno być 'doX:' w dwóch ostatnich urywkach –

Odpowiedz

7

Zacznę drodze zwykle zdefiniowania klasy:

function CustomDataType(a) 
{ 
    this.a = a; 
    this.b = 2; 
} 
CustomDataType.prototype = { 
    doX : function() {} 
}; 
var obj = new CustomDataType(1); 

przypisać zmienne w konstruktorze ponieważ F.prototype = { a : [1,2,3]; } jest problematyczne, tablica będzie dzielona między instancji, chyba że nieruchomość jest ponownie inicjowane w konstruktorze (problematyczne dla wszystkich typów nie pierwotnych). Jest również potrzebny, gdy właściwość w jakiś sposób zależy od argumentów konstruktora. Deklaruję metody w prototypie, tak aby były one współużytkowane przez wszystkie instancje, jeśli korzystasz z dziedziczenia, oznacza to, że możesz mieć super-wywołania, to również spowoduje mniejsze zużycie pamięci, ponieważ metoda musi zostać przydzielona tylko raz (chociaż to prawdopodobnie nie jest " duży problem).

Nigdy nie użyłem Object.create, nie widzę żadnego powodu, aby to zrobić, chyba że jesteś w jakimś szalonym dynamicznym hackery.

Używam literałów obiektów, gdy wydaje się zbędne tworzenie oddzielnej klasy dla obiektów, na przykład jeśli są to argumenty dla metod (aby wywoływacze nie musiały jawnie tworzyć czegoś) lub jeśli są to wartości wewnętrzne, które powinny być dostępne dla kogokolwiek innego.

Twoja fabryka jest w zasadzie taka sama, jak literał obiektu. Przypuszczam, że może się to przydać, jeśli potrzebujesz stworzyć jsonową strukturę i ustawić niektóre wartości domyślne.

Nie rozumiem, dlaczego new byłoby niebezpieczne lub niepotrzebne, w jakim kontekście to powiedział?

Ale myślę, że wiele z nich sprowadza się do smaku. Bądź konsekwentny i nie komplikuj rzeczy.

+2

Problem Crockforda z 'new' jest:" * Jeśli zapomnisz dołączyć prefiks 'new' podczas wywoływania funkcji konstruktora, wtedy' this' will nie być związanym z nowym obiektem, ale niestety, będzie to związane z obiektem globalnym, więc zamiast powiększać twój nowy obiekt, będziesz przejmował globalne zmienne Znacznie lepszą alternatywą jest nie używanie "nowych" w ogóle. * " – DCoder

+1

Ah, pamiętam, że czytałem o tym, prawdopodobnie od niego. Możesz zrobić coś takiego, jak 'funkcja C (x) {jeśli (to == okno) zwraca nowe C (x); this.x = x; } ' Często psuje mi się, gdy piszę JS, ale nigdy nie zapomniałem napisać' new' ... –

+0

@AdamBergmark czy nie lepiej byłoby podać błąd, aby wymusić użycie nowego? – Dreamwalker

Powiązane problemy