Ejemplo de operador ternario de JavaScript con funciones

91

Estoy usando jQuery 1.7.1

Estoy empezando a usar el operador ternario de JavaScript para reemplazar declaraciones simples if / else. Lo he hecho con éxito en varios lugares. Me sorprendió cuando logré lograr que algo más funcionara cuando pensé que seguro que no lo haría, pero lo intenté de todos modos.

Aquí está la declaración original:

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    if (IsChecked == true){
        removeItem($this);
    } else {
        addItem($this);
    }
}

Aquí está la misma función usando el operador ternario:

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    (IsChecked == true) ? removeItem($this) : addItem($this);
}

Me sorprendió porque todos los ejemplos que vi que se usaban simplemente configuraban variables como esta:

x = (1 < 2) ? true : false;

Mi pregunta es si este es un uso "normal" y si funcionará en la mayoría de las versiones de JavaScript. ¿Dónde fallará? ¿Hay otros usos menos obvios para él?

ACTUALIZACIÓN - ¡Gracias por el consejo del "mundo real"!

Estoy usando esto como mi función:

function updateItem() {
    $this = $(this);
    $this.hasClass("IsChecked") ? removeItem($this) : addItem($this);
}
Evik James
fuente
Es normal y funcionará bien. En general, la legibilidad es difícil cuando se usan operadores ternarios, pero en su caso se ve bien.
Selvakumar Arumugam
1
Hmm ... también podrías hacer esto ya que ambos aceptan los mismos argumentos (IsChecked ? removeItem : addItem)($this). Sin embargo, para responder a su pregunta, sí, esto es normal y no hay nada de malo en usar operadores ternarios siempre que no disminuyan la capacidad de mantenimiento o la legibilidad en una situación en la que sea necesario. jsfiddle.net/vsB3f
Kevin B
if($this.hasClass("IsChecked")) removeItem($this); else addItem($this)es la forma correcta. El operador ternario no está diseñado para casos como este, sino para cosas como foo(isChecked ? 'bar' : meow());(es decir, cuando le importa el "valor de retorno" de lo que haga en los bloques then / else)
ThiefMaster
1
En su ejemplo, omita la primera línea a favor de esto: $(this).hasClass("IsChecked") ? removeItem($this) : addItem($this); puedo entender su código tal como está en una línea, por lo que se ajusta a mi regla general (vea la publicación a continuación). Funciona para mi.
Surreal Dreams

Respuestas:

189

Je, hay algunos usos bastante interesantes de la sintaxis ternaria en tu pregunta; Me gusta el último el mejor ...

x = (1 < 2) ? true : false;

El uso de ternario aquí es totalmente innecesario; simplemente podría escribir

x = (1 < 2);

Del mismo modo, el elemento de condición de una declaración ternaria siempre se evalúa como un valor booleano, por lo tanto, puede expresar:

(IsChecked == true) ? removeItem($this) : addItem($this);

Simplemente como:

(IsChecked) ? removeItem($this) : addItem($this);

De hecho, también eliminaría el IsCheckedtemporal que te deja con:

($this.hasClass("IsChecked")) ? removeItem($this) : addItem($this);

En cuanto a si esta es una sintaxis aceptable, ¡seguro que lo es! Es una excelente manera de reducir cuatro líneas de código en una sin afectar la legibilidad. El único consejo que le daría es que evite anidar múltiples declaraciones ternarias en la misma línea (¡de esa manera se encuentra la locura!)

JonnyReeves
fuente
tenga en cuenta que es posible que desee evitar el uso de mayúsculas en los nombres de las clases (IsChecked se convierte en está marcado) stackoverflow.com/questions/1547986/…
Adrien Be
JS tiene funciones de primera clase:($this.hasClass("isChecked") ? removeItem : addItem)($this)
ClojureMostly
22

El estilo ternario se usa generalmente para ahorrar espacio. Semánticamente, son idénticos. Prefiero ir con la sintaxis completa if / then / else porque no me gusta sacrificar la legibilidad: soy de la vieja escuela y prefiero mis llaves.

El formato completo if / then / else se usa para casi todo. Es especialmente popular si ingresa a bloques de código más grandes en cada rama, tiene un árbol if / else ramificado muti, o múltiples else / ifs en una cadena larga.

El operador ternario es común cuando está asignando un valor a una variable en función de una condición simple o está tomando decisiones múltiples con resultados muy breves. El ejemplo que cita en realidad no tiene sentido, porque la expresión evaluará uno de los dos valores sin ninguna lógica adicional.

Buenas ideas:

this > that ? alert(this) : alert(that);  //nice and short, little loss of meaning

if(expression)  //longer blocks but organized and can be grasped by humans
{
    //35 lines of code here
}
else if (something_else)
{
    //40 more lines here
}
else if (another_one)  /etc, etc
{
    ...

Menos bueno:

this > that ? testFucntion() ? thirdFunction() ? imlost() : whathappuh() : lostinsyntax() : thisisprobablybrokennow() ? //I'm lost in my own (awful) example by now.
//Not complete... or for average humans to read.

if(this != that)  //Ternary would be done by now
{
    x = this;
}
else
}
    x = this + 2;
}

Una regla empírica realmente básica : ¿puedes entender todo el asunto tan bien o mejor en una línea? Ternario está bien. De lo contrario, amplíelo.

Sueños surrealistas
fuente
7

No hay nada particularmente complicado en el ejemplo que publicaste.

En un operador ternario, se evalúa el primer argumento (el condicional) y si el resultado es true, se evalúa y se devuelve el segundo argumento; de lo contrario, se evalúa y se devuelve el tercero. Cada uno de esos argumentos puede ser cualquier bloque de código válido, incluidas las llamadas a funciones.

Piénsalo de esta manera:

var x = (1 < 2) ? true : false;

También podría escribirse como:

var x = (1 < 2) ? getTrueValue() : getFalseValue();

Esto es perfectamente válido y esas funciones pueden contener cualquier código arbitrario, ya sea que esté relacionado con la devolución de un valor o no. Además, los resultados de la operación ternaria no tienen que asignarse a nada, al igual que los resultados de las funciones no tienen que asignarse a nada:

(1 < 2) ? getTrueValue() : getFalseValue();

Ahora simplemente reemplácelos con cualquier función arbitraria, y se quedará con algo como su ejemplo:

(1 < 2) ? removeItem($this) : addItem($this);

Ahora, su último ejemplo realmente no necesita un ternario, ya que se puede escribir así:

x = (1 < 2);  // x will be set to "true"
Jeff B
fuente
7

También me gustaría agregar algo mío.

Otra posible sintaxis para llamar a funciones con el operador ternario, sería:

(condition ? fn1 : fn2)();

Puede ser útil si tiene que pasar la misma lista de parámetros a ambas funciones, por lo que debe escribirlos solo una vez.

(condition ? fn1 : fn2)(arg1, arg2, arg3, arg4, arg5);

Puede usar el operador ternario incluso con nombres de función miembro, que personalmente me gusta mucho para ahorrar espacio:

$('.some-element')[showThisElement ? 'addClass' : 'removeClass']('visible');

o

$('.some-element')[(showThisElement ? 'add' : 'remove') + 'Class']('visible');

Otro ejemplo:

var addToEnd = true; //or false
var list = [1,2,3,4];
list[addToEnd ? 'push' : 'unshift'](5);
Bartłomiej Zalewski
fuente
6

Si va a anidar operadores ternarios, creo que querrá hacer algo como esto:

   var audience = (countrycode == 'eu') ? 'audienceEU' :
                  (countrycode == 'jp') ? 'audienceJP' :
                  (countrycode == 'cn') ? 'audienceCN' :
                  'audienceUS';

Es mucho más eficiente escribir / leer que:

var audience = 'audienceUS';
if countrycode == 'eu' {
   audience = 'audienceEU';
} else if countrycode == 'jp' {
   audience = 'audienceJP';
} else if countrycode == 'cn' {
   audience = 'audienceCN';
}

Al igual que con toda buena programación, los espacios en blanco hacen que todo sea agradable para las personas que tienen que leer su código después de que haya terminado con el proyecto.

Sam W
fuente
6
Totalmente en desacuerdo con su comentario anterior sobre que el ternario anidado es más fácil de leer y depurar. Personalmente, preferiría ver el bloque anidado else / if reemplazado por una tabla de búsqueda o una declaración de cambio.
JonnyReeves
@JonnyReeves estuvo de acuerdo: por lo general, la sintaxis ternaria anidada se usa mejor cuando se verifican diferentes condiciones (por ejemplo, módulo de números )
AlexFoxGill
2

Sé que la pregunta ya está respondida.

Pero permítanme agregar un punto aquí. Este no es solo el caso de verdadero o falso. Vea abajo:

var val="Do";

Var c= (val == "Do" || val == "Done")
          ? 7
          : 0

Aquí, si val es Do o Done, c será 7; de lo contrario, será cero. En este caso c será 7.

Esta es en realidad otra perspectiva de este operador.

Himanshu Tiwari
fuente