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?
Entiendo que 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 nulo o indefinido, pero no he logrado encontrar mucho material de referencia sobre esta técnica y tengo visto que se usa mucho.
Además, ¿es esta técnica específica de JavaScript? Sé que hacer algo similar en PHP daría como resultado f
un verdadero valor booleano, en lugar del valor de d
sí mismo.
$f=$a or $f=$b or $f=$c; // etc
. PHP tiene tanto el||
operador como elor
operador, que hacen el mismo trabajo; sin embargo,or
se evalúa después de la asignación mientras||
se evalúa antes. Esto también le da el estilo de$a=getSomething() or die('oops');
$f = $a ?: $b ?: $c;
??
para esto.$a = $b ?? 'default'
$a
se le asignará el valor de$b
si$b
es verdadero, otro'default'
?Respuestas:
Ver evaluación de cortocircuito para la explicación. Es una forma común de implementar estos operadores; No es exclusivo de JavaScript.
fuente
if( true == f )
. Si se almacenó un número entero en f, entonces esta prueba siempre devolverá falso.if(true == f)
, que es lo mismo queif(f)
: la prueba pasará. Si también desea probar el tipo def
, utilice una comparación estricta:if(true === f)
que fallará de hecho.Esto se hace para asignar un valor predeterminado , en este caso el valor de
y
, si lax
variable es falsa .Los operadores booleanos en JavaScript pueden devolver un operando, y no siempre un resultado booleano como en otros idiomas.
El operador lógico OR (
||
) devuelve el valor de su segundo operando, si el primero es falso, de lo contrario se devuelve el valor del primer operando.Por ejemplo:
Falsy valores son los que coaccionar a
false
cuando se utiliza en contexto booleano, y son0
,null
,undefined
, una cadena vacía,NaN
y por supuestofalse
.fuente
||
exclusivo.&&
operador lógico tiene un comportamiento similar, devuelve el valor del primer operando si es falso y devuelve el valor del segundo operando, solo si el primero es verdadero , por ejemplo,("foo" && "bar") == "bar"
y(0 && "bar") == 0
Javacript utiliza la evaluación de cortocircuito para operadores lógicos
||
y&&
. Sin embargo, es diferente a otros idiomas en que devuelve el resultado del último valor que detuvo la ejecución, en lugar de un valortrue
ofalse
.Los siguientes valores se consideran falsos en JavaScript.
""
(cuerda vacía)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.
Los primeros 5 valores hasta
NaN
son falsos, por lo que todos se evalúan de izquierda a derecha, hasta que cumpla con el primer valor"Hello"
verdadero, lo que hace que toda la expresión sea verdadera, por lo que todo lo que esté más arriba no se evaluará y"Hello"
se devolverá como resultado de la expresión . Del mismo modo, en este caso:Los primeros 5 valores son todos verdaderos y se evalúan hasta que cumple con el primer valor falso (
null
) que hace que la expresión sea falsa, por2010
lo que ya no se evalúa ynull
se devuelve como resultado de la expresión.El ejemplo que ha dado es hacer uso de esta propiedad de JavaScript para realizar una tarea. Se puede usar en cualquier lugar donde necesite obtener el primer valor verdadero o falso entre un conjunto de valores. Este código a continuación asignará el valor
"Hello"
ab
, ya que facilita la asignación de un valor predeterminado, en lugar de hacer verificaciones if-else.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.
Dentro de la alerta, verificamos si
messages
es falso y, en caso afirmativo, evaluamos y devolvemosnoNewMessagesText
, de lo contrario, evaluamos y devolvemosnewMessagesText
. Como es falso en este ejemplo, nos detenemos en noNewMessagesText y alertamos"Sorry, you have no new messages."
.fuente
However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of a true, or false value.
Las variables de Javascript no están escritas, por lo que a f se le puede asignar un valor entero aunque se haya asignado a través de operadores booleanos.
A f se le asigna el valor más cercano que no es equivalente a falso . Entonces 0, falso, nulo, indefinido, se pasan por alto:
fuente
''
también igual falso en este caso.f is assigned the NEAREST value
es un punto bastante importante aquí.||
operador booleano , al ser un operador booleano, tiene dos operandos: un lado izquierdo y un lado derecho. Si el lado izquierdo del||
es verdadero , la operación se resuelve hacia el lado izquierdo y se ignora el lado derecho. Si el lado izquierdo es falso , se resuelve hacia el lado derecho. Pornull || undefined || 4 || 0
lo tanto, en realidad se resuelveundefined || 4 || 0
qué resuelve a4 || 0
qué se resuelve4
.No hay ninguna magia en ello. Las expresiones booleanas como
a || b || c || d
se evalúan perezosamente. Interpeter busca el valor dea
, es indefinido, por lo que es falso, por lo que sigue adelante, luego veb
cuál es nulo, lo que todavía da un resultado falso, por lo que sigue adelante, luego ve lac
misma historia. Finalmente ved
y dice 'eh, no es nulo, así que tengo mi resultado' y lo asigna a la variable final.Este truco funcionará en todos los lenguajes dinámicos que hacen una evaluación de cortocircuito diferido de expresiones booleanas. En lenguajes estáticos no se compilará (error de tipo). En los lenguajes que están ansiosos por evaluar expresiones booleanas, devolverá un valor lógico (es decir, verdadero en este caso).
fuente
d
se asignará si fue nulo / indefinido o no.||
operador siempre resuelve todo el operando del lado derecho cuando el lado izquierdo es falso. Al ser un operador booleano, solo ve dos entradas: el lado izquierdo y el lado derecho. El analizador no los ve como una serie de términos, por lo que en realidad no se detiene cuando encuentra el primer valor verdadero a menos que ese valor sea también el operando de la mano izquierda de otro||
.Esta pregunta ya ha recibido varias buenas respuestas.
En resumen, esta técnica aprovecha una característica de cómo se compila el lenguaje. Es decir, JavaScript "cortocircuita" la evaluación de los operadores booleanos y devolverá el valor asociado con el primer valor de la variable no falsa o lo que contenga la última variable. Vea la explicación de Anurag de esos valores que se evaluarán como falsos.
Usar esta técnica no es una buena práctica por varias razones; sin embargo.
Características documentadas: existe una alternativa existente que satisface esta necesidad y es coherente en más idiomas. Este sería el operador ternario:
()? valor 1: valor 2.
El uso del operador ternario requiere un poco más de tipeo, pero distingue claramente entre la expresión booleana que se evalúa y el valor que se asigna. Además, se puede encadenar, por lo que se podrían recrear los tipos de tareas predeterminadas que se realizan anteriormente.
fuente
potentially be targeted for change in the future.
Sí, pero no, eso se aplica a JavaScript.a || b || c || d || e
?Devuelve el primer valor verdadero de salida .
Si todos son falsos, devuelva el último valor falso.
Ejemplo:-
fuente
Establece la nueva variable (
z
) en el valor dex
si es "verdadero" (distinto de cero, un objeto / matriz / función válido / lo que sea) o de loy
contrario. Es una forma relativamente común de proporcionar un valor predeterminado en caso de quex
que no exista.Por ejemplo, si tiene una función que toma un parámetro opcional de devolución de llamada, podría proporcionar una devolución de llamada predeterminada que no haga nada:
fuente
Significa que si
x
se establece, el valorz
seráx
, de lo contrario, siy
se establece, su valor se establecerá como elz
valor de 's.es lo mismo que
Es posible porque los operadores lógicos en JavaScript no devuelven valores booleanos, pero el valor del último elemento necesario para completar la operación (en una oración OR sería el primer valor no falso, en una oración AND sería el último ) Si la operación falla,
false
se devuelve.fuente
||
operador solo devuelve el segundo valor, independientemente de si es verdadero o no.z
se establece en el valor dex
si ese valor es verdadero . De lo contrario, se establece en el valor dey
. Esto significa que six
se establece en, por ejemplo,0
o la cadena vacía""
, esto no hace lo que usted dice, ya que esos valores son falsos .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 podría usarse para establecer un valor predeterminado para el argumento de la función.
fuente
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.
Producirá 'bob';
fuente
false
, pero las matrices u objetos vacíos obligan atrue
.De acuerdo con la publicación del blog de Bill Higgins ; el lenguaje de asignación OR lógico de Javascript (febrero de 2007), este comportamiento es cierto a partir de v1.2 (al menos)
También sugiere otro uso para él (citado): " normalización ligera de las diferencias entre navegadores "
fuente