En javascript, cuando se usa una declaración if con múltiples condiciones para probar, ¿javascript las prueba todas independientemente, o se resguardará antes de probarlas todas si ya es falsa?
Por ejemplo:
a = 1
b = 2
c = 1
if (a==1 && b==1 && c==1)
¿Javascript probará las 3 condiciones o, después de ver que b no es igual a 1 y, por lo tanto, es falso, saldrá de la declaración?
Pregunto desde el punto de vista del desempeño. Si, por ejemplo, estoy probando 3 selectores complejos de jQuery, preferiría que jQuery no atraviese el DOM 3 veces si es obvio a través del primero que devolverá FALSO. (En cuyo caso, tendría más sentido anidar 3 declaraciones if).
ADDENDUM: Más que una curiosidad, ¿cuál es el término adecuado para esto? Noto que muchos de ustedes usan el término "cortocircuito". Además, ¿algunos idiomas hacen esto y otros no?
fuente
Respuestas:
El
&&
operador "cortocircuita", es decir, si la condición de la izquierda es falsa, no se molesta en evaluar la correcta.De manera similar, el
||
operador cortocircuita si la condición izquierda es verdadera.EDITAR: Sin embargo, no debe preocuparse por el rendimiento hasta que haya evaluado y determinado que es un problema. La microoptimización prematura es la pesadilla de la mantenibilidad.
fuente
if (!barSticky && bar.parent().offset().top <= document.documentElement.scrollTop)
la segunda condición es un cálculo más costoso, la primera es solo un booleano. :)Desde el punto de vista del rendimiento, esto no es una microoptimización.
Si tenemos 3 variables booleanas, a, b, c, eso es una microoptimización.
Si llamamos a 3 funciones que devuelven variables booleanas, cada función puede llevar bastante tiempo, y no solo es importante conocer estos cortocircuitos, sino en qué orden. Por ejemplo:
es mucho mejor que
si es igualmente probable que ambos devuelvan falso.
fuente
Es por eso que puedes hacer en código javascript como
Lo que significaría que si x no está definido o es 'falso', el valor predeterminado es 2.
fuente
En caso de que alguien se pregunte si hay una manera de forzar la evaluación de todas las condiciones, en algunos casos se pueden usar los operadores bit a bit
&
y|
Estos deben usarse con mucho cuidado porque los operadores bit a bit son operadores aritméticos que funcionan en bits individuales de su operando y no siempre pueden funcionar como una versión "sin cortocircuito" de
&&
y||
Ejemplo:
pero
Espero que ayude a alguien que llegó aquí buscando información como esta (como yo) y gracias a @Max por la corrección y el contraejemplo
fuente
false && (alert(""))
solución funcionara: /var a=false; var b=check(); alert(a && b);
Solo probará todas las condiciones si las primeras son verdaderas, pruébelo usted mismo:
fuente
Se produce un cortocircuito: solo se compararán a y b en su ejemplo.
fuente
Otra razón por la cual detener la evaluación con 1 o más parámetros a la izquierda.
if (response.authResponse && (response.authResponse.accessToken! = user.accessToken)) {...}
la segunda evaluación se basa en que la primera es verdadera y no arrojará un error de compilación si response.authResponse es nulo o indefinido, etc. porque la primera condición falló.
Otros lenguajes tuvieron este problema en los primeros días y creo que ahora es un enfoque estándar en la creación de compiladores.
fuente
Sale después de ver que b no es igual a uno.
fuente
Para cualquiera en esta pregunta confundido porque no está viendo el comportamiento de cortocircuito cuando usa un
||
junto con un?
operador así:x = 1 || true ? 2 : 3 // value of x will be 2, rather than 1 as expected
parece que la regla de cortocircuito no funciona. ¿Por qué está evaluando el segundo término del
||
(¿verdadero? 2: 3) cuando el primero es verdadero? Resulta ser un problema de orden de operaciones porque lo anterior es equivalente ax = (1 || true) ? 2 : 3
con el
||
evaluado primero y el?
evaluado segundo. Lo que probablemente quieras es:x = 1 || (true ? 2 : 3)
fuente