Em javascript, ao usar uma instrução if com várias condições para testar, o javascript testa todas elas independentemente, ou vai parar antes de testar todas se já for falso?
Por exemplo:
a = 1
b = 2
c = 1
if (a==1 && b==1 && c==1)
O javascript testará todas as 3 dessas condições ou, depois de ver que b não é igual a 1 e, portanto, é falso, sairá da instrução?
Eu pergunto do ponto de vista do desempenho. Se, por exemplo, estou testando 3 seletores jQuery complexos, prefiro que o jQuery não atravesse o DOM 3 vezes se for óbvio pelo primeiro que ele retornará FALSO. (Nesse caso, faria mais sentido aninhar 3 instruções if).
ADENDO: Mais curiosidade, qual o termo adequado para isso? Percebi que muitos de vocês usam o termo 'curto-circuito'. Além disso, alguns idiomas fazem isso e outros não?
fonte
Respostas:
O
&&
operador "causa um curto-circuito" - isto é, se a condição da esquerda for falsa, ele não se preocupa em avaliar a condição da direita.Da mesma forma, o
||
operador entra em curto-circuito se a condição à esquerda for verdadeira.EDIT: Porém, você não deve se preocupar com o desempenho até que tenha feito o benchmarking e determinado que é um problema. A micro-otimização prematura é a ruína da manutenção.
fonte
if (!barSticky && bar.parent().offset().top <= document.documentElement.scrollTop)
a segunda condição é um cálculo mais caro, a primeira é apenas um booleano. :)Do ponto de vista do desempenho, isso não é uma micro-otimização.
Se tivermos 3 variáveis booleanas, a, b, c, isso é uma micro-otimização.
Se chamarmos 3 funções que retornam variáveis booleanas, cada função pode levar muito tempo, e não só é importante saber quais são os curtos-circuitos, mas em que ordem. Por exemplo:
é muito melhor que
se ambos têm a mesma probabilidade de retornar false.
fonte
É por isso que você pode fazer em código javascript como
O que significa que se x for indefinido ou 'falso', o valor padrão é 2.
fonte
No caso de alguém está se perguntando se existe uma maneira de forçar a avaliação de todas as condições, em alguns casos, os operadores bit a bit
&
e|
pode ser usadoEles devem ser usados com muito cuidado porque os operadores bit a bit são operadores aritméticos que funcionam em bits únicos de seu operando e nem sempre podem funcionar como uma versão "sem curto-circuito" de
&&
e||
Exemplo:
mas
Espero que ajude quem chegou aqui em busca de informações como esta (como eu) e obrigado ao @Max pela correção e contra-exemplo
fonte
false && (alert(""))
solução funcionar: /var a=false; var b=check(); alert(a && b);
Ele só testará todas as condições se as primeiras forem verdadeiras, teste você mesmo:
fonte
Ele causa um curto-circuito - apenas aeb serão comparados em seu exemplo.
fonte
Outro motivo para interromper a avaliação com 1 ou mais parâmetros à esquerda.
if (response.authResponse && (response.authResponse.accessToken! = user.accessToken)) {...}
a segunda avaliação depende de a primeira ser verdadeira e não gerará um erro de compilação se response.authResponse for nulo ou indefinido etc porque a primeira condição falhou.
Outras linguagens tiveram esse problema no início e acho que é uma abordagem padrão na construção de compiladores agora.
fonte
Ele sai depois de ver que b não é igual a um.
fonte
Para qualquer um sobre esta questão confuso porque não está vendo o comportamento de curto-circuito ao usar um
||
em conjunto com um?
operador como este:x = 1 || true ? 2 : 3 // value of x will be 2, rather than 1 as expected
parece que a regra de curto-circuito não está funcionando. Por que está avaliando o segundo termo do
||
(verdadeiro? 2: 3) quando o primeiro é verdadeiro? Acontece que é um problema de ordem de operações porque o acima é equivalente ax = (1 || true) ? 2 : 3
com o
||
primeiro avaliado e o?
segundo avaliado. O que você provavelmente quer é:x = 1 || (true ? 2 : 3)
fonte