2012-11-19 12 views
6

Io uso spesso var options = options || {} come metodo predefinito per un oggetto vuoto. Viene spesso utilizzato per inizializzare un oggetto opzione nel caso in cui non sia passato nel parametro di una chiamata di funzione.Differenza tra `var options = options || {} `e` opzioni || (opzioni = {}) `

Il fatto è che ho letto in diversi punti (post di blog, codice sorgente) che options || (options = {}) esprime meglio l'intento dello sviluppatore. Qualcuno può elaborarlo? Non vedo la differenza funzionale tra i due, quindi c'è qualcosa che mi manca qui.

--- modificare

ho visto in Backbone.js codice sorgente in diversi luoghi, come https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L273

penso l'ho visto troppo in codice sorgente di jQuery troppo. E nelle molteplici J che scrivono le guide di stile che sono fiorite.

--- Edit 2 esempio di codice:

var func = function(param, options) { 
    // How I do it 
    var options = options || {}; 
    // How I should do it in the "same" way 
    options = options || {}; 
    // The "other" way 
    options || (options = {}); 

} 
+0

Puoi collegare ad alcuni di questi post? –

+0

Questo è soggettivo IMHO, personalmente mi piace quello che preferisci, loro fanno davvero la stessa cosa. –

+1

Normalmente farei 'opzioni = opzioni || {} ', senza ri-dichiarare la variabile con' var'. Peccato che non ci sia '|| =' in Javascript – Kos

risposta

3

dovrebbero fare la stessa cosa, ma c'è un modo migliore.

In teoria il secondo, assegnando solo se il valore è falsi, può eliminare un compito ed essere più veloce. Infatti in un jsperf vediamo che è (12%).

Infatti l'esplicito if è altrettanto veloce come la condizione-then-assegnazione:

if(!options) 
    options = {}; 

Try the test on your browser/machine.

Penso che l'esplicito se sia il più chiaro e non ha penalità.

Edit:

Se vi aspettate un oggetto per essere passato a una funzione, allora penso che la prova migliore è:

if(typeof options !== 'object') 
    options = {}; 

Questo farà sì che si dispone di un oggetto in seguito , anche se è vuoto. Qualsiasi altro test (per indefinito o falsità) consentirà un vero non-oggetto attraverso come un numero diverso da zero o una stringa non vuota. Tuttavia, come mostra jsperf, questo è ~ 15% più lento. Dal momento che si esegue questa operazione solo quando si accede a una funzione che elabora gli oggetti, direi che è un compromesso utile, ed è appena più lento dell'assegnare sempre.

+0

Ho provato il jsperf, utilizzando Chrome 23. Fondamentalmente nessuna differenza. – DjebbZ

+0

@DjebbZ: Esattamente, fai il più leggibile, non ci sono altri vantaggi tranne l'esplicito test dell'ultimo test. –

4

Non c'è una differenza funzionale.

Il secondo costrutto solo (soggettivamente) sembra come fa quello che fa più del primo costrutto.

L'argomento contatore è che il primo costrutto è un modello comune, quindi è più facilmente riconosciuto fare ciò che fa.

+0

D'accordo, per qualcuno che non è troppo vicino con JavaScript, la prima notazione sembrerebbe più comprensibile . – naivists

5

Non c'è differenza, supponendo che significava:

function fn(options) { 
    // type a 
    options = options || {}; 

    // type b 
    options || (options = {}); 
} 

soprattutto una questione di preferenza, credo (a) è un bel po 'più chiaro, non mi piace la dichiarazione con alcuna assegnazione sul lato sinistro .

1

Non c'è davvero alcuna differenza funzionale tra i due, anche se i loro meccanismi non sono identici.

Il primo modulo imposta la variabile locale options come uguale al parametro options o su un oggetto vuoto se l'argomento ha un valore di falsi (ad esempio se non è stato fornito).

Il secondo modulo valuta il valore del parametro options (se non è falsi), altrimenti valuta il risultato dell'assegnazione dell'oggetto vuoto a quel parametro. Quindi la differenza dal primo modulo è che se options è veritiero, non viene eseguita alcuna assegnazione.

Personalmente ritengo la seconda forma di essere una versione meno leggibile di

if(!options) { 
    options = {}; 
} 

al quale è identica sia funzione e meccanica.

1

Non v'è alcuna differenza funzionale, l'idea è che options || (options = {}); è più vicino a quello che il programmatore davvero voglio esprimere, che è in realtà:

if (typeof options == "undefined") { 
    options = {}; 
} 

L'operatore || viene utilizzato per rendere il codice più corto, non codice più chiaro.

+0

C'è un bel gap tra falsy e undefined, quindi se vuoi davvero scavalcare undefined, fallo esplicitamente. –

+0

@PhilH: Sì, c'è una lacuna, ma nessuna delle due versioni è in grado di gestire tutti i valori nell'intervallo. Entrambe le versioni lasciano alcuni valori che sono inutili in questo contesto, come ad esempio 'true', scivolano e lasciano il resto del codice soffocare su di loro. – Guffa

+0

Molto vero. Questo è uno dei lati negativi di un linguaggio digitato in modo dinamico. –

0

Definitivamente soggettivo, ma non utilizzerei il secondo.

Motivo: Sento che i compiti nelle espressioni sono più profondi del livello superiore = offuscamento.

Alcuni programmatori C simili (una volta, una volta), fanno cose come extra paren per rendere l'assegnazione più chiara ... rendendo l'intera espressione non familiare. Perché preoccuparsi se puoi essere semplice?

La più chiara sarebbe probabilmente:

if (!options) options = {}; 
2

C'è una differenza funzionale: uno usa var e l'altro no. Se esiste la possibilità che la variabile options non esista nello scope corrente, è molto meglio usare var piuttosto che rischiare che lo options diventi implicitamente in ambiti esterni.

Se opzioni è garantita esistere (per esempio, in una funzione i cui parametri comprendono options), le due istruzioni sono funzionalmente identiche così il problema si riduce per i meriti stilistici di options = options || {} rispetto options || (options = {}). Personalmente vedo poca differenza: entrambi richiedono la stessa conoscenza di come funziona l'operatore di JavaScript ||, quindi una volta rimosso tale fattore dall'equazione, probabilmente preferirei options = options || {} come leggermente più leggibile in virtù del fatto che è più breve e più semplice. L'intenzione dello sviluppatore mi sembra altrettanto chiara in entrambi i casi.

+0

Sì, certo. Ho dimenticato di aggiungere un po 'di codice per renderlo esplicito, dove la variabile 'options' esiste effettivamente nei parametri della funzione. Quindi, mentre il tuo punto è molto valido, non ha alcun impatto nel mio caso. – DjebbZ