2013-03-30 11 views
6

Ho visto molte volte che fn && fn() è un'ottimizzazione di if (fn) fn()."if (fn) fn()" o "fn && fn()"

La mia domanda è: perché? e qual è il codice generato per entrambe le soluzioni?

+2

Cosa intendi per "codice generato"? – Kobi

+0

@Kobi Immagino che voglia dire che cosa è stato compilato il codice JavaScript in questione - il codice di basso livello. – kba

+0

@kobi, kba ha ragione, intendo il codice di basso livello, assemblatore. –

risposta

13

Il && operatore in JavaScript è cortocircuitato, il che significa che se il lato sinistro è false, il lato destro non viene valutato affatto. Ecco perché fn && fn() è sicuro anche se fn è falso (null, undefined, ecc.).

Il "codice generato" dipenderà interamente dal motore JavaScript, ma mi aspetterei che sia abbastanza simile in entrambi i casi (&& e if).

Non è una "ottimizzazione", nel senso di correre più veloce, ma piuttosto nel senso di essere più breve di scrivere (in modo particolare se, come me, si mai lasciare {} off if dichiarazioni). Ha lo svantaggio di essere leggermente meno chiaro per le persone che sono nuove alla lingua, ma è un idioma imparato in fretta.

+0

Non sarebbe più sicuro fare 'typeof fn ===" function "'? – Antony

+0

@Antony: Sì, lo farebbe. Vedete questo idioma in luoghi in cui il codice si aspetta una funzione o nulla (per esempio, un argomento di funzione opzionale), e le persone tendono ad accettarlo se falliscono se gli date qualcosa, ma la cosa che gli dai non è Una funzione, sulla teoria che la documentazione per la funzione (per esempio) dice che è possibile fornire una funzione o nulla, ma non una funzione o (per esempio) una stringa. :-) Inoltre, alcune funzioni fornite dall'host su alcuni motori hanno 'typeof'' "oggetto" '(purtroppo) ma sono ancora richiamabili. –

2

Quindi, per if (fn) fn(), è necessario assicurarsi che fn sia già esistente prima di eseguirlo. la condizione if verifica un valore booleano o un'espressione, in JavaScript qualsiasi valore di falsy può assumere un valore false nella condizione di controllo booleano if. valori Falsy potrebbero essere:

  • falsa
  • nullo
  • indefinito
  • La stringa vuota ''
  • Il numero 0
  • Il numero NaN (sì, 'non è un numero' è un numero, è un numero speciale )

qualsiasi altro valore sarà un valore reale e.

Quindi, se il fn è un valore null o undefined, il controllo if vi proteggerà da esecuzione di un oggetto non funzioni.

Per fn && fn(), si sta facendo lo stesso: in JavaScript, l'espressione booleana è pigro controllata che significa che se la prima parte, in un'operazione &&, è falsa, la seconda parte non verrà eseguita. Pertanto, con questa funzione, è possibile proteggere il codice dall'esecuzione di un oggetto non funzionale.

fn && fn() non è una versione ottimizzata dell'altro in termini di prestazioni ma è una versione breve in forma scritta.

Entrambi i snippet di codice richiedono una condizione preliminare: la funzione fn potrebbe non essere definita o un oggetto funzione reale. Se nel codice, il fn ha la possibilità di essere un oggetto di altri tipi, come ad esempio una stringa, è necessario aggiungere il tipo di controllo prima di eseguire, come ad esempio:

if (fn instanceof Function) fn()

0

In termini di ottimizzazione, IMHO, direi proprio perché è un modo migliore di renderlo una linea se poi, senza dover sacrificare le parentesi e compromettendo la leggibilità, ma non renderebbe il codice più veloce da eseguire

Problemi correlati