Operadores lógicos Javascript: AND e OR
Aprenda quando usar && e ||, como o curto-circuito funciona de verdade, por que esses operadores retornam valores (e não apenas booleanos) e quais padrões evitam bugs em validação, guard clauses e defaults.
Economize R$320 na compra do seu curso. Use o código e comece a aprender!
Desenvolva sites e aplicativos ágeis e intuitivos. Aprenda a estruturar com HTML, estilizar com CSS e Bootstrap, criar interatividade com JavaScript e gerenciar estados e componentes com React e Recoil. Torne-se um desenvolvedor Front-end e comece sua carreira no aquecido mercado de TI.
Os operadores lógicos em JavaScript são ferramentas centrais para escrever decisões no código. Você usa
&&
quando todas as condições precisam ser verdadeiras e
||
quando basta uma delas ser verdadeira. Até aqui, simples.
O detalhe que costuma gerar bugs é que, no JavaScript,
&&
e
||
não retornam necessariamente
true
ou
false
. Eles retornam um dos operandos avaliados. Junto com o curto-circuito, isso cria padrões muito úteis, mas também armadilhas se você não entender a regra.
Quando usar AND e OR em JavaScript
Use
&&
quando você quer garantir que todas as condições sejam atendidas.
- Exemplo mental: “só entra se tiver documento e bilhete”
- Exemplo no código:
if (isLogged && hasTicket) {
enter();
}
Use
||
quando qualquer uma das condições já resolve.
- Exemplo mental: “entra se for admin ou owner”
- Exemplo no código:
if (role === 'admin' || role === 'owner') {
openAdminPanel();
}
Valores por omissão (“fallback”): || devolve o primeiro valor “truthy” (verdadeiro em contexto lógico). Ótimo para defaults, mas atenção: 0 e ” são “falsy”. Se 0 ou ” forem válidos, prefira ?? (nullish coalescing), que só recorre ao valor por omissão quando o dado é null ou undefined.
const page = userInput || 1; // 0 vira 1 (cuidado!)
const pageSafe = userInput ?? 1; // 0 permanece 0 (melhor quando 0 é válido)
Combinar condições: use parênteses para clareza.
if (isLogged && (isAdmin || isOwner)) {
// ...
}
Dica rápida: “truthy/falsy” no JS — false, 0, -0, 0n, ”, null, undefined e NaN são “falsy”. Quase tudo o resto é “truthy”.
AND (&&): como funciona na prática
O && avalia da esquerda para a direita e para assim que encontra um valor falsy.
Se o primeiro operando for falsy, ele retorna esse operando e não avalia o resto.
Se todos forem truthy, ele retorna o último operando.
Exemplos rápidos:
'JS' && 42 // → 42 (ambos truthy, retorna o último)
'' && 'algo' // → '' (pára no falsy à esquerda)
true && 'ok' // → 'ok'
false && doWork() // → false (doWork NEM é chamado)
Isto permite executar algo só se uma condição for verdadeira:
isReady && start(); // chama start() só se isReady for truthy
user && user.login && init(); // evita erro quando user/login podem faltar
Curto-circuito e valores devolvidos
Curto-circuito significa: se o resultado já está decidido, o JavaScript não avalia o restante.
No
A && B
:
- Se
Afor falsy, o resultado éAeBnão é executado.
Isso é útil para evitar chamadas desnecessárias e efeitos colaterais:
// Só calcula se realmente precisar
const expensive = () => computeBigReport();
const result = hasPermission && expensive(); // computeBigReport() corre só quando precisa
Também permite padrões de execução condicional:
const name = user && user.profile && user.profile.name; // pode ser undefined
// Versão moderna e mais segura:
const nameSafe = user?.profile?.name; // optional chaining
Atenção: isso é prático, mas pode reduzir legibilidade em regras complexas. Em fluxos críticos, um if explícito pode ser melhor.
Exemplos de condições (validação, cláusula de guarda)
1) Validação rápida de campos
Quando todos os campos precisam existir:
const valid = name && email && password;
if (valid) {
submitForm();
} else {
showError("Preencha todos os campos.");
}
Nota importante:
valid
não será booleano necessariamente. Pode ser o valor de
password
(se tudo for truthy) ou o primeiro falsy encontrado. Se você precisa de booleano, converta.
const validBool = Boolean(name && email && password);
2) Cláusula de guarda
Sair cedo quando não dá para continuar:
function sendNewsletter(user) {
if (!user || !user.email) return;
sendEmail(user.email);
}
Em geral, guard clause explícita com
if
é mais clara do que encadear
&&
em acesso profundo.
3) Acesso seguro encadeado
Padrão antigo com
&&
:
const name = user && user.profile && user.profile.name;
Padrão moderno recomendado com optional chaining:
const nameSafe = user?.profile?.name;
Erros comuns
Confundir bitwise com lógico: & e | não são && e ||. Bitwise opera em bits e devolve números, quebrando a lógica.
// Errado:
if (isReady & hasTicket) { ... } // pode virar 0 ou 1 e dar falso-positivo
Usar || para valor por omissão quando 0/” são válidos: troque por ??.
const qty = input ?? 0; // e não input || 0
Esperar booleano de &&/||: eles retornam valores. Se precisa de true/false, converta:
const isOk = !!(a && b);
Esquecer parênteses e criar precedências confusas:
// Melhor explícito
if (isLogged && (isAdmin || isOwner)) { ... }
Contar com “truthiness” sem saber o que é truthy/falsy: arrays ([]) e objetos ({}) são sempre truthy, mesmo vazios.
if ([]) { /* entra aqui */ } // verdade
Executar funções sem querer no lado esquerdo:
// Errado: a função executa SEMPRE, antes de && avaliar
doSideEffect() && proceed();
// Certo: avalie a condição primeiro
condition && proceed();
Encadear acesso com && quando há ?.: prefira optional chaining pela clareza e pelos erros evitados.
const street = user?.address?.street;
OR (||): como funciona na prática
||
avalia da esquerda para a direita e retorna o primeiro operando “truthy” que encontrar. Se todos forem “falsy”, retorna o último.
‘a’ || ‘b’ // → ‘a’ (primeiro truthy)
” || ‘padrão’ // → ‘padrão’ (” é falsy)
0 || 10 // → 10 (0 é falsy)
null || undefined || ‘ok’ // → ‘ok’
false || 0 || ” // → ” (todos falsy → retorna o último)
({}) || ‘x’ // → {} (objetos são sempre truthy)
Esse comportamento é ótimo para pegar a primeira alternativa válida e para fallbacks simples:
const data = getFromCache() || fetchFromApi(); // só busca se o cache for falsy
const name = userInput || 'Anônimo'; // usa um nome padrão
Curto-circuito e valores retornados
Em
A || B
, se
A
já é truthy, o JavaScript nem avalia
B
. Isso evita trabalho desnecessário (ou efeitos colaterais) no segundo operando:
const primary = () => readPrimary(); // pode ser caro
const backup = () => readBackup();
const value = primary() || backup(); // backup() só roda se primary() retornar algo falsy
Lembre-se:
||
não retorna um booleano, retorna um dos operandos. Se você precisa de
true/false
, converta:
const hasName = !!(user.name || user.nickname);
Valores padrão
||
é frequente em defaults, mas com um detalhe importante: ele trata
''
,
0
,
false
e
NaN
como “vazios” (falsy). Se 0 ou ” são valores válidos, prefira
??
(nullish coalescing), que só cai para o padrão quando o valor é
null
ou
undefined
.
// Com || você perde 0 e '' como valores válidos:
const page = userInput || 1; // userInput = 0 → vira 1 (talvez indesejado)
const headline = title || 'Sem título'; // title = '' → vira 'Sem título'
// Com ?? você preserva 0 e '':
const pageSafe = userInput ?? 1; // 0 permanece 0
const headlineSafe = title ?? 'Sem título'; // '' permanece ''
Combine
||
com
?
. (optional chaining) para fallback quando a propriedade pode não existir:
const city = user?.address?.city || ‘Desconhecida’;
Se
''
for um valor aceitável para
city
, troque por
??
:
const citySafe = user?.address?.city ?? 'Desconhecida';
Duas alternativas modernas a
||
para defaults:
// Parâmetro com default
function list(page = 1) { /* ... */ }
// Atribuição lógica (ES2021)
config.port ||= 8080; // só define se config.port for falsy
Erros comuns
1. Usar OR para default onde 0/”/false são válidos
Se esses valores são legítimos, use
??
:
const qty = input ?? 0; // em vez de input || 0
2. Confundir
|
(bitwise) com
||
(lógico)
|
opera em bits e retorna número — pode quebrar a condição.
// Errado:
if (isReady | hasTicket) { ... }
3. Esperar booleano de
||
||
retorna um valor, não
true/false
. Converta quando precisar:
const ok = !!(a || b);
4. Misturar
??
com
||
sem parênteses (SyntaxError)
O JavaScript exige parênteses ao combinar
??
com
||
/
&&
:
// Errado: a ?? b || c
const out = (a ?? b) || c; // Certo
5. Precedência confusa com
&&
&&
tem maior precedência que
||
. Deixe explícito:
if ((isLogged && isAdmin) || isOwner) { ... }
6. Executar o fallback do lado esquerdo por engano
O que está antes de
||
é sempre avaliado. Evite colocar chamadas caras ali quando a ideia era só um valor:
// Prefira:
const cfg = cached || readConfig(); // readConfig() só roda se cached for falsy
Conclusão
- Escolha certa: use
&&quando tudo precisa ser verdadeiro; use||quando basta uma condição. - Curto-circuito + retorno de valores:
&&e||não retornam booleanos — devolvem um dos operandos e podem pular parte da expressão. - Defaults com segurança:
||serve para fallback rápido, mas se0,''oufalseforem válidos, prefira??. - Padrões seguros: execução condicional com
cond && run(), cláusula de guarda no início das funções e acesso opcional comobj?.prop?.subprop. - Evite armadilhas: não confunda &/| (bitwise) com &&/|| (lógicos); respeite a precedência (
&&antes de||) e use parênteses para clareza; quando precisar de booleano, use!!(expr). - Performance e efeitos colaterais: coloque chamadas caras no lado que pode ser pulado pelo curto-circuito (
primary() || backup(), isReady && start()).
Se você lembrar só disso, já escreve condições mais claras, seguras e fáceis de manter.
Desenvolvimento Front-end do Zero ao Pro
Economize R$320 na compra do seu curso. Use o código e comece a aprender!
Desenvolva sites e aplicativos ágeis e intuitivos. Aprenda a estruturar com HTML, estilizar com CSS e Bootstrap, criar interatividade com JavaScript e gerenciar estados e componentes com React e Recoil. Torne-se um desenvolvedor Front-end e comece sua carreira no aquecido mercado de TI.
Receba artigos do blog, acompanhe as últimas notícias da EBAC e fique por dentro das novidades!