JavaScript OR (||) spiegazione di assegnazione variabile

Dato questo snippet di JavaScript …

var a; var b = null; var c = undefined; var d = 4; var e = 'five'; var f = a || b || c || d || e; alert(f); // 4 

Qualcuno può spiegarmi come si chiama questa tecnica (la mia ipotesi migliore è nel titolo di questa domanda!)? E come / perché funziona esattamente?

La mia comprensione è che alla variabile f verrà assegnato il valore più vicino (da sinistra a destra) della prima variabile che ha un valore che non è né nullo né indefinito, ma non sono riuscito a trovare molto materiale di riferimento su questa tecnica e l’ho visto usato molto.

Inoltre, questa tecnica è specifica per JavaScript? So che fare qualcosa di simile in PHP comporterebbe che f avesse un vero valore booleano, piuttosto che il valore di d stesso.

Vedi la valutazione del cortocircuito per la spiegazione. È un modo comune per implementare questi operatori; non è univoco per JavaScript.

Questo è fatto per assegnare un valore predefinito , in questo caso il valore di y , se la variabile x è falsa .

Gli operatori booleani in JavaScript possono restituire un operando e non sempre un risultato booleano come in altre lingue.

L’operatore logico OR ( || ) restituisce il valore del suo secondo operando, se il primo è falso, altrimenti viene restituito il valore del primo operando.

Per esempio:

 "foo" || "bar"; // returns "foo" false || "bar"; // returns "bar" 

I valori di Falsy sono quelli che costringono a false quando vengono utilizzati nel contesto booleano e sono 0 , null , undefined , una stringa vuota, NaN e ovviamente false .

Javacript utilizza la valutazione di cortocircuito per gli operatori logici || e && . Tuttavia, è diverso dalle altre lingue in quanto restituisce il risultato dell’ultimo valore che ha interrotto l’esecuzione, anziché un valore true o false .

I seguenti valori sono considerati falsi in JavaScript.

  • falso
  • nullo
  • "" (stringa vuota)
  • 0
  • Nan
  • non definito

Ignorando le regole di precedenza degli operatori e mantenendo le cose semplici, i seguenti esempi mostrano quale valore ha fermato la valutazione e come risultato viene restituito.

 false || null || "" || 0 || NaN || "Hello" || undefined // "Hello" 

I primi 5 valori fino a NaN sono falsi, quindi sono tutti valutati da sinistra a destra, finché non raggiunge il primo valore di verità – "Hello" che rende vera l’intera espressione, quindi qualsiasi cosa più in alto non sarà valutata, e "Hello" diventa restituito come risultato dell’espressione. Allo stesso modo, in questo caso:

 1 && [] && {} && true && "World" && null && 2010 // null 

I primi 5 valori sono tutti veri e vengono valutati fino a quando non incontra il primo valore di falsy ( null ) che rende l’espressione falsa, quindi 2010 non viene più valutata e null viene restituito come risultato dell’espressione.

L’esempio che hai dato sta facendo uso di questa proprietà di JavaScript per eseguire un compito. Può essere utilizzato ovunque sia necessario ottenere il primo valore di verità o di falsità tra un insieme di valori. Questo codice di seguito assegnerà il valore "Hello" a b in quanto rende più semplice assegnare un valore predefinito, invece di fare i controlli if-else.

 var a = false; var b = a || "Hello"; 

Potresti chiamare l’esempio seguente come uno sfruttamento di questa funzione, e credo che renda il codice più difficile da leggere.

 var messages = 0; var newMessagesText = "You have " + messages + " messages."; var noNewMessagesText = "Sorry, you have no new messages."; alert((messages && newMessagesText) || noNewMessagesText); 

All’interno dell’avviso, controlliamo se i messages sono falsi e, in caso affermativo, valutiamo e restituiamo noNewMessagesText , altrimenti valutiamo e restituiamo newMessagesText . Dato che in questo esempio è falsato, ci fermiamo a noNewMessagesText e allertiamo "Sorry, you have no new messages." .

Le variabili Javascript non sono state digitate, quindi f può essere assegnato un valore intero anche se è stato assegnato tramite operatori booleani.

f è assegnato il valore più vicino che non è equivalente a falso . Quindi 0, falso, nullo, non definito, vengono tutti passati:

 alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4' 

Non c’è alcuna magia ad esso. Espressioni booleane come a || b || c || d a || b || c || d a || b || c || d sono pigramente valutati. Interpeter cerca il valore di a , non è definito, quindi è falso così che si muova, quindi vede b che è nullo, che dà comunque risultato falso così che si muova, quindi vede c – stessa storia. Alla fine vede d e dice ‘huh, non è nulla, quindi ho il mio risultato’ e lo assegna alla variabile finale.

Questo trucco funzionerà in tutti i linguaggi dinamici che eseguono una valutazione pigro del cortocircuito delle espressioni booleane. Nei linguaggi statici non verrà compilato (errore di digitazione). Nelle lingue che sono desiderose di valutare le espressioni booleane, restituirà il valore logico (vale a dire vero in questo caso).

Questa domanda ha già ricevuto diverse buone risposte.

In sintesi, questa tecnica sta sfruttando una funzionalità di come viene compilato il linguaggio. Cioè, JavaScript “cortocircuita” la valutazione degli operatori booleani e restituirà il valore associato al primo valore variabile non falso o qualunque sia l’ultima variabile contenuta. Vedi la spiegazione di Anurag di quei valori che valuteranno come falsi.

L’utilizzo di questa tecnica non è una buona pratica per diversi motivi; però.

  1. Leggibilità del codice: utilizza operatori booleani e, se il comportamento di come compila non viene compreso, il risultato previsto sarebbe un valore booleano.
  2. Stabilità: si sta utilizzando una funzionalità di come viene compilata la lingua che è incoerente in più lingue e, a causa di ciò, è qualcosa che potrebbe potenzialmente essere preso di mira per il cambiamento in futuro.
  3. Funzionalità documentate: esiste un’alternativa esistente che soddisfa questa esigenza ed è coerente in più lingue. Questo sarebbe l’operatore ternario:

    ()? valore 1: valore 2.

L’uso dell’operatore ternario richiede un po ‘più di digitazione, ma distingue chiaramente tra l’espressione booleana valutata e il valore assegnato. Inoltre può essere concatenato, quindi i tipi di assegnazioni predefinite eseguite sopra potrebbero essere ricreati.

 var a; var b = null; var c = undefined; var d = 4; var e = 'five'; var f = ( a ) ? a : ( b ) ? b : ( c ) ? c : ( d ) ? d : e; alert(f); // 4 

Imposta la nuova variabile ( z ) sul valore di x se è “sincero” (non zero, object / matrice / funzione valido / qualunque esso sia) o altrimenti. È un modo relativamente comune di fornire un valore predefinito nel caso in cui x non esista.

Ad esempio, se si dispone di una funzione che accetta un parametro di callback facoltativo, è ansible fornire un callback predefinito che non esegue alcuna operazione:

 function doSomething(data, callback) { callback = callback || function() {}; // do stuff with data callback(); // callback will always exist } 

Restituisce il primo valore vero dell’output.

Se tutto è falso, restituisci l’ultimo valore falso.

Esempio:-

  null || undefined || false || 0 || 'apple' // Return apple 

Significa che se x è impostato, il valore per z sarà x , altrimenti se y è impostato, il suo valore sarà impostato come valore della z .

è lo stesso di

 if(x) z = x; else z = y; 

È ansible perché gli operatori logici in JavaScript non restituiscono valori booleani ma il valore dell’ultimo elemento necessario per completare l’operazione (in una frase OR sarebbe il primo valore non falso, in una frase AND sarebbe l’ultimo ). Se l’operazione fallisce, viene restituito false .

Si chiama Operatore di corto circuito.

La valutazione di cortocircuito dice che il secondo argomento viene eseguito o valutato solo se il primo argomento non è sufficiente per determinare il valore dell’espressione. quando il primo argomento della funzione OR (||) restituisce true, il valore complessivo deve essere true.

Potrebbe anche essere usato per impostare un valore predefinito per l’argomento della funzione

 function theSameOldFoo(name){ name = name || 'Bar' ; console.log("My best friend's name is " + name); } theSameOldFoo(); // My best friend's name is Bar theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar` 

Valuterà X e, se X non è nullo, la stringa vuota, o 0 (logico falso), quindi lo assegnerà a z. Se X è nullo, la stringa vuota o 0 (logico falso), assegnerà y a z.

 var x = ''; var y = 'bob'; var z = x || y; alert(z); 

Produrrà “bob”;

Secondo il post sul blog di Bill Higgins ; l’idioma di assegnazione logica OR Javascript (febbraio 2007), questo comportamento è vero a partire dalla v1.2 (almeno)

Suggerisce anche un altro uso per questo (citato): ” normalizzazione leggera delle differenze tra browser

 // determine upon which element a Javascript event (e) occurred var target = /*w3c*/ e.target || /*IE*/ e.srcElement;