JavaScript O (||) explicación de asignación de variable

Dado este fragmento de 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 

¿Puede alguien explicarme cómo se llama esta técnica (mi mejor conjetura está en el título de esta pregunta)? ¿Y cómo / por qué funciona exactamente?

Según entiendo, a la variable f se le asignará el valor más cercano (de izquierda a derecha) de la primera variable que tenga un valor que no sea ni nulo ni indefinido, pero no he logrado encontrar mucho material de referencia sobre esta técnica y lo he visto usado mucho

Además, ¿esta técnica es específica de JavaScript? Sé que hacer algo similar en PHP daría como resultado f tener un verdadero valor booleano, en lugar del valor de d mismo.

Ver evaluación de cortocircuitos para la explicación. Es una forma común de implementar estos operadores; no es exclusivo de JavaScript.

Esto se hace para asignar un valor predeterminado , en este caso el valor de y , si la variable x es faly .

Los operadores booleanos en JavaScript pueden devolver un operando y no siempre un resultado booleano como en otros idiomas.

El operador OR lógico ( || ) devuelve el valor de su segundo operando, si el primero es falso, de lo contrario, se devuelve el valor del primer operando.

Por ejemplo:

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

Los valores de Falsy son aquellos que fuerzan a false cuando se usan en contexto booleano, y son 0 , null , undefined , una cadena vacía, NaN y por supuesto false .

Javacript utiliza evaluación de cortocircuito para operadores lógicos || y && . Sin embargo, es diferente a otros lenguajes en que devuelve el resultado del último valor que detuvo la ejecución, en lugar de un valor true o false .

Los siguientes valores se consideran falsos en JavaScript.

  • falso
  • nulo
  • "" (cadena vacía)
  • 0
  • Yaya
  • indefinido

Ignorando las reglas de precedencia del operador y manteniendo las cosas simples, los siguientes ejemplos muestran qué valor detuvo la evaluación y se devuelve como resultado.

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

Los primeros 5 valores hasta NaN son falsos, por lo que se evalúan de izquierda a derecha hasta que coincidan con el primer valor verdadero: "Hello" que hace que toda la expresión sea verdadera, por lo que no se evaluará nada y se obtendrá "Hello" regresó como resultado de la expresión. Del mismo modo, en este caso:

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

Los primeros 5 valores son todos verdaderos y se evalúan hasta que cumplan con el primer valor falso ( null ) que hace que la expresión sea falsa, por lo que 2010 ya no se evalúa y se devuelve null como resultado de la expresión.

El ejemplo que ha dado es el uso de esta propiedad de JavaScript para realizar una tarea. Se puede usar en cualquier lugar donde necesite obtener el primer valor de falsedad o verdad entre un conjunto de valores. Este código a continuación asignará el valor "Hello" a b , ya que facilita la asignación de un valor predeterminado, en lugar de hacer verificaciones if-else.

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

Podría llamar al ejemplo siguiente una explotación de esta característica, y creo que hace que el código sea más difícil de leer.

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

Dentro de la alerta, verificamos si los messages son falsos, y si es así, entonces evalúa y devuelve noNewMessagesText , de lo contrario evalúa y devuelve newMessagesText . Como es falso en este ejemplo, nos detenemos en noNewMessagesText y alertamos "Sorry, you have no new messages." .

Las variables de Javascript no se escriben, por lo que a f se le puede asignar un valor entero aunque se haya asignado a través de operadores booleanos.

f tiene asignado el valor más cercano que no es equivalente a falso . Entonces 0, falso, nulo, indefinido, se pasan por alto:

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

No hay magia para eso. Expresiones booleanas como a || b || c || d a || b || c || d a || b || c || d son evaluados perezosamente. Interpeter busca el valor de a , está indefinido, por lo que es falso, por lo que se mueve, luego ve a b que es nulo, lo que da un resultado falso, por lo que se mueve, luego ve c – la misma historia. Finalmente ve d y dice ‘eh, no es nulo, entonces tengo mi resultado’ y lo asigna a la variable final.

Este truco funcionará en todos los lenguajes dynamics que hacen evaluación de cortocircuito perezoso de expresiones booleanas. En lenguajes estáticos no comstackrá (escriba error). En los idiomas que están ansiosos por evaluar expresiones booleanas, devolverá el valor lógico (es decir, verdadero en este caso).

Esta pregunta ya recibió varias buenas respuestas.

En resumen, esta técnica aprovecha una característica de cómo se comstack el idioma. Es decir, JavaScript “cortocircuita” la evaluación de operadores booleanos y devolverá el valor asociado con el primer valor de variable no falsa o con lo que contenga la última variable. Consulte la explicación de Anurag de aquellos valores que se evaluarán como falsos.

El uso de esta técnica no es una buena práctica por varias razones; sin embargo.

  1. Capacidad de lectura del código: Esto está utilizando operadores booleanos, y si el comportamiento de cómo se comstack no se entiende, entonces el resultado esperado sería un valor booleano.
  2. Estabilidad: se trata de utilizar una característica de la comstackción del lenguaje que no es consistente en varios idiomas, y debido a esto, es algo que podría ser el objective de un cambio en el futuro.
  3. Características documentadas: existe una alternativa existente que satisface esta necesidad y es consistente en más idiomas. Este sería el operador ternario:

    ()? valor 1: valor 2.

Usar el operador ternario requiere un poco más de tipeo, pero distingue claramente entre la expresión booleana que se evalúa y el valor asignado. Además, se puede encadenar, por lo que se podrían recrear los tipos de asignaciones predeterminadas que se realizan anteriormente.

 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 

Está estableciendo la nueva variable ( z ) en el valor de x si es “verdad” (distinto de cero, un objeto / matriz / función / lo que sea) o de lo contrario. Es una forma relativamente común de proporcionar un valor predeterminado en caso de que x no exista.

Por ejemplo, si tiene una función que toma un parámetro de callback opcional, puede proporcionar una callback predeterminada que no hace nada:

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

Devuelve el primer valor verdadero de salida.

Si todos son falsos, devuelva el último valor falso.

Ejemplo:-

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

Significa que si se establece x , el valor de z será x ; de lo contrario, si se establece y, entonces su valor se establecerá como el valor de z .

es lo mismo que

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

Es posible porque los operadores lógicos en JavaScript no devuelven valores booleanos sino el valor del último elemento necesario para completar la operación (en una oración O sería el primer valor no falso, en una oración AND sería el último ) Si la operación falla, se devuelve false .

Se llama operador de cortocircuito.

La evaluación de cortocircuito dice que el segundo argumento se ejecuta o evalúa solo si el primer argumento no es suficiente para determinar el valor de la expresión. cuando el primer argumento de la función OR (||) se evalúa como verdadero, el valor general debe ser verdadero.

También se podría usar para establecer un valor predeterminado para el argumento de la función.

 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` 

Evaluará X y, si X no es nulo, la cadena vacía, o 0 (falso lógico), entonces lo asignará a z. Si X es nulo, la cadena vacía, o 0 (falso lógico), entonces asignará y a z.

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

Producirá ‘bob’;

De acuerdo con la publicación del blog de Bill Higgins ; el lenguaje de asignación de O lógico Javascript (febrero de 2007), este comportamiento es verdadero a partir de v1.2 (al menos)

También sugiere otro uso (citado): ” normalización ligera de las diferencias entre navegadores

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