Executando verificação de segurança...
6

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
Carregando publicação patrocinada...
2