Operatore ternario Javascript vs. ||


17

Stavo dando un'occhiata ad alcuni codici node.js in precedenza e ho notato che il ragazzo che lo ha scritto sembrava favorire la seguente sintassi:

var fn = function (param) {
    var paramWithDefault = null == param ? 'Default Value' : param;
}

Su quello che considero più conciso:

var fn = function (param) {
    var paramWithDefault = param || 'Default Value';
}

Mi chiedevo se la seconda forma fosse in realtà una sintassi JavaScript socialmente più accettabile, l'ho vista in natura più volte dell'operatore ternario per questo scopo.

Noto che nel primo esempio sta usando il doppio uguale (non il triplo uguale), il che significa che conterà "indefinito" come nullo, il che ridurrebbe un impatto a cui potrei pensare. Tuttavia, ho letto in numerosi punti che == è un operatore piuttosto malvagio in JavaScript (JSLint è decisamente contrario, IIRC).


2
Commentatori: i commenti hanno lo scopo di cercare chiarimenti, non di discussioni estese. Se hai una soluzione, lascia una risposta. Se la tua soluzione è già stata pubblicata, ti preghiamo di votarla. Se desideri discutere questa domanda con altri, utilizza la chat . Vedi le FAQ per maggiori informazioni.

Risposte:


17

Perché questo codice verrebbe valutato su "Valore predefinito" ogni volta che passavi 0, "", falso o qualche altro valore di falsa.

function fn(param) {
  var paramWithDefault = param || 'Default Value';
  return paramWithDefault;
}

Potrebbe non morderti su come usi questa particolare funzione, ma è un cattivo modello da evitare quando ti interessa passare cose come stringhe vuote o 0 o un valore booleano.


dovresti usare solo una coalescenza nulla su un oggetto e se un oggetto è definito, allora non funzionerà. Con forse l'eccezione della stringa vuota.
Malfist,

4
Il confronto zero è un buon punto, che potrebbe essere abbastanza inaspettato.
Ed James,

1
+1 - questo problema è precisamente il motivo per cui Python (alla fine) ha aggiunto la sintassi "x if y else z". Quelle semantiche per gli operatori logici sono abbastanza comuni e gli stessi errori comuni tendono ad apparire ogni volta che i modi di dire si affidano a loro per fare il lavoro degli operatori di selezione condizionale.
Steve314,

non dimenticare di mettere i tuoi costrutti tra parentesi, se li usi insieme alla concatenazione di stringhe var txt = 'Hello, ' + (user_name||'User') + '!';funzionerà, ma senza parentesi - otterrai undefined. jsfiddle.net/4mFAB/1
c69

7

Ciò di cui hai veramente bisogno è un operatore di coalescenza nullo. Ma visto che javascript non ne ha davvero uno, i programmatori in genere usano '||' per sostituirlo.

Tuttavia, entrambi sono perfettamente ragionevoli. Per quelli che non capiscono cosa sia un operatore di coalescenza nulla, è probabile che l'operatore ternario abbia maggiori probabilità di essere compreso.


Un altro operatore correlato è l'operatore Icona scritto IIRC "altro". Ciò riconosce uno speciale risultato "fail" dal primo argomento e utilizza il secondo argomento in quel caso come alternativa. Vorrei che Pythons "x if y else z" fosse implementato usando due operatori separati - un operatore di asserzione binaria "if" e un operatore "else" simile a un'icona - con quei due operatori utilizzabili in modo indipendente. Tuttavia, Icon non ha supportato quello stile, facendo invece qualcosa di bizzarro con i relativi operatori.
Steve314,

@ Steve314: Python ha qualcosa che volevi: un altro operatore [false-part, true-part]separato con un operatore separato se [..][bool(condition)]combinato [false-part, true-part][bool(condition)]. Se vuoi un comportamento pigro, puoi semplicemente lambda la parte vera e falsa.
Lie Ryan,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.