Operador ternario de Javascript vs. ||

17

Estaba mirando algún código de node.js antes, y noté que el tipo que lo escribió parecía favorecer la siguiente sintaxis:

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

Sobre lo que considero más conciso:

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

Me preguntaba si la segunda forma es en realidad una sintaxis JavaScript más socialmente aceptable, la he visto en la naturaleza más veces que el operador ternario para este propósito.

Observo que en el primer ejemplo está usando los dobles iguales (no los triples iguales), lo que significa que contará "indefinido" como nulo, lo que reduciría un impacto en el que podría pensar. Sin embargo, he leído en numerosos lugares que == es un operador bastante malvado en JavaScript (JSLint está muy en contra, IIRC).

Ed James
fuente
2
Comentaristas: los comentarios están destinados a buscar aclaraciones, no para una discusión prolongada. Si tiene una solución, deje una respuesta. Si su solución ya está publicada, favor de votarla. Si desea discutir esta pregunta con otras personas, utilice el chat . Consulte las preguntas frecuentes para obtener más información.

Respuestas:

17

Debido a que este código se evaluaría a 'Valor predeterminado' cada vez que pasara 0, "", falso o algún otro valor falso.

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

Puede que no te muerda cómo usas esta función en particular, pero es un mal patrón para evitar cuando te importa pasar cosas como cadenas vacías o 0 o un booleano.

Peter Smith
fuente
solo debe usar una fusión nula en un objeto, y si se define un objeto, esto no funcionará. Con tal vez la excepción de la cadena vacía.
Malfist
44
La comparación cero es un buen punto, que podría ser bastante inesperado.
Ed James
1
+1: este problema es precisamente por qué Python (eventualmente) agregó la sintaxis "x if y else z". Esa semántica para operadores lógicos es bastante común, y los mismos errores comunes tienden a surgir cada vez que las expresiones idiomáticas dependen de ellos para hacer el trabajo de los operadores de selección condicional.
Steve314
simplemente no olvide poner sus construcciones entre paréntesis, si las usa junto con la concatenación de cadenas var txt = 'Hello, ' + (user_name||'User') + '!';funcionará, pero sin paréntesis, obtendrá undefined. jsfiddle.net/4mFAB/1
c69
7

Lo que realmente necesita es un operador de fusión nula. Pero al ver que javascript realmente no tiene uno, los programadores suelen usar '||' para sustituirlo.

Sin embargo, ambos son perfectamente razonables. Para aquellos que no entienden qué es un operador de fusión nula, es probable que el operador ternario sea más comprensible.

Malfist
fuente
Otro operador relacionado es el operador Icon escrito IIRC "else". Esto reconoce un resultado especial de "falla" del primer argumento, y utiliza el segundo argumento en ese caso como alternativa. Me gustaría que las pitones "x if y else z" se implementaran utilizando dos operadores separados: un operador de aserción binaria "if" y un operador "else" similar a un icono, con esos dos operadores que se pueden usar de forma independiente. Sin embargo, Icon no admitía ese estilo, sino que hacía algo extraño con los operadores relativos.
Steve314
@ Steve314: Python tiene algo que querías: un operador distinto por separado [false-part, true-part]con un operador si separado [..][bool(condition)]combinado en [false-part, true-part][bool(condition)]. Si desea un comportamiento perezoso, simplemente puede lambda la parte verdadera y falsa.
Lie Ryan