Segundo a especificação da linguagem esses são os Binary Logical Operators. Um detalhe importante é que em JavaScript o resultado não necessariamente é um valor booleano, pois esses operadores sempre retornam o valor de um dos operandos.
Isso porque em JavaScript qualquer valor pode ser usado em um contexto booleano. Existem os chamados truthy values e falsy values, ou seja, valores que são considerados true
ou false
quando usados em um contexto booleano. Basicamente, o número zero, ""
(string vazia), null
, undefined
e NaN
são considerados falsos (além, é claro, do próprio booleano false
), e qualquer outro valor é considerado verdadeiro.
Ou seja, se eu tiver algo como console.log('a' || 20)
, isso irá imprimir a string "a" (pois ela é considerada true
, e o operador ||
retorna o primeiro operando se este for true
, caso contrário retorna o segundo). E console.log('a' && 20)
imprime 20
, pois o operador &&
retorna o primeiro operando se este for false
, caso contrário retorna o segundo.
Por isso é comum ter coisas como:
x = valor1 || valor2 || valor3;
Ou seja, x
recebe o primeiro dos valores que não for falsy (ou o último, caso todos sejam). Isso só é possÃvel porque o operador retorna um dos operandos, ou seja, ao final é garantido que algum dos valores será atribuÃdo a x
. Seria equivalente a isso:
if (valor1) {
x = valor1;
} else if (valor2) {
x = valor2;
} else {
x = valor3;
}
Repare que o último não precisa testar, pois se chegou ali é porque todos os anteriores são falsy values e o retorno será valor3
de qualquer jeito.
Outro detalhe importante é que esses operadores são "short-circuit", ou seja, nem sempre ambos os operandos serão avaliados.
No caso do ||
, se um dos operandos é verdadeiro, então a expressão toda será. Por isso, se o primeiro for verdadeiro, ele nem avalia o segundo. Exemplo:
function primeiro() {
console.log('primeiro');
return 1;
}
function segundo() {
console.log('segundo');
return 2;
}
if (primeiro() > 0 || segundo() > 0) {
console.log('ok');
}
A saÃda deste código é:
primeiro
ok
Ou seja, ele avaliou a primeira condição (verifica se o retorno da função primeiro()
é maior que zero), e como esta é verdadeira, ele nem precisou avaliar a segunda.
De forma similar, o operador &&
é verdadeiro apenas se ambos os operandos também forem verdadeiros. Então se o primeiro for falso, ele nem avalia o segundo:
function primeiro() {
console.log('primeiro');
return 1;
}
function segundo() {
console.log('segundo');
return 2;
}
if (primeiro() < 0 && segundo() > 0) {
console.log('ok');
}
Agora ele avalia a expressão primeiro() < 0
, e como o resultado é falso, o resultado do operador é false
e ele nem avalia a segunda expressão. Por isso a saÃda é apenas:
primeiro