2013-04-07 9 views
8

Supponi di creare il tipo di dati e di esporne il comportamento.Javascript: quali sono alcune linee guida su come definire nuovi tipi di dati?

Può darci qualche esempio di quando si usa:

  • una funzione & nuova:

    // 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(); 
    
  • un oggetto letterale & 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); 
    
  • una funzione che ti costruisce r oggetto:

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

sento che questo potrebbe essere etichettato duplicato per: new vs Object.create ma il mio interesse principale non è in discussione che uno è meglio, ma piuttosto di sapere se ci sono casi di utilizzo specifici in cui si dovrebbe essere preferito agli altri.

Ho letto molti post su domande correlate e il libro di Crockford: Javascript: le parti buone. Finora ho concluso che è una questione di preferenza, il consiglio di Crockford risuona molto con me per me: "cerca di evitare le caratteristiche che sono pericolose e non necessarie" ... Sto parlando di new.

+0

La prima e la terza versione mettono le proprietà direttamente sul nuovo oggetto. Nella tua seconda versione, l'oggetto eredita le proprietà. Non so che ci sia una risposta concreta alla tua domanda. Il primo usa un costruttore se invochi l'uso di 'new', e' instanceof' funzionerà per identificare quell'oggetto.Il terzo non richiede l'uso di 'new', ma' instanceof' non sarà così utile. Il secondo eredita di nuovo le proprietà, quindi la creazione di più oggetti in questo modo condividerà tutti i dati e tutti gli oggetti osserveranno gli aggiornamenti dell'oggetto ereditato. –

+0

... e non essere troppo preso dagli avvertimenti di pericolo di Crockford. Penso che si preoccupi un po 'troppo. Voglio dire, prendi tutto, ma prendilo con un pizzico di sale. –

+1

'this.doX =' dovrebbe essere 'doX:' negli ultimi due snippet –

risposta

7

Comincerò con il mio modo di solito definisco classi:

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

assegno variabili nel costruttore perché F.prototype = { a : [1,2,3]; } è problematico, l'array sarà condiviso tra le istanze meno che la proprietà viene reinizializzata nel costruttore (problematico per tutti i tipi non primitivi). Ed è anche necessario quando la proprietà dipende in qualche modo dagli argomenti del costruttore. Dichiaro i metodi nel prototipo in modo che siano condivisi tra tutte le istanze, se si utilizza l'ereditarietà significa che è possibile avere chiamate super, ma anche un minore utilizzo della memoria poiché il metodo deve essere assegnato una sola volta (anche se probabilmente non lo è) t un grosso problema).

Non ho mai usato Object.create, non vedo alcun motivo per farlo, a meno che non ci si trovi in ​​qualche folle incitamento dinamico.

Io uso i letterali oggetto ogni volta che non è necessario creare una classe separata per gli oggetti, ad esempio se si tratta di argomenti su un metodo (quindi i chiamanti non devono istanziare esplicitamente qualcosa), o se sono alcuni valori interni che non dovrebbero accesso a chiunque altro

La vostra fabbrica è essenzialmente la stessa dell'oggetto letterale. Suppongo che possa essere utile se è necessario creare una struttura jsonesque e impostare alcuni valori predefiniti.

Non vedo perché new sarebbe pericoloso o non necessario, in che contesto ha detto questo?

Ma penso che molte cose si riducano al gusto. Sii coerente e non complicare le cose.

+2

Il problema di Crockford con 'new' è:" * Se si dimentica di includere il prefisso 'new' quando si chiama una funzione di costruzione, allora' this' will non essere legato a un nuovo oggetto. Purtroppo, questo sarà legato all'oggetto globale, quindi, invece di aumentare il tuo nuovo oggetto, sarai in balle delle variabili globali. Un'alternativa molto migliore è quella di non usare "new". * " – DCoder

+1

Ah, ricordo di aver letto su questo, probabilmente da lui. Si potrebbe fare qualcosa come 'function C (x) {if (this == window) restituisce new C (x); this.x = x; } ' Mi capita molto quando scrivo JS, ma non ho mai dimenticato di scrivere' new' ... –

+0

@AdamBergmark non sarebbe meglio lanciare un errore per forzare l'utilizzo di new? – Dreamwalker

Problemi correlati