Operadores em JavaScript
Esta aula aborda os operadores em JavaScript, incluindo aritméticos, de comparação, lógicos, operadores modernos (??, ?., spread/rest) e precedência. O conteúdo é aprofundado com exemplos práticos e exercícios para fixação.
Nesta aula, você aprenderá sobre os operadores em JavaScript, fundamentais para realizar operações em variáveis e valores. Entenderemos desde os operadores aritméticos básicos até os modernos operadores de coalescência nula (??), encadeamento opcional (?.) e spread/rest. Além disso, veremos como a precedência dos operadores afeta a execução das expressões.
Os operadores são símbolos que instruem o interpretador a realizar operações específicas, como matemática, comparação ou lógica. Dominá-los é essencial para escrever código eficiente e evitar bugs comuns.
Aritméticos
Os operadores aritméticos são usados para realizar operações matemáticas em números. JavaScript oferece os operadores tradicionais: adição (+), subtração (-), multiplicação (*), divisão (/) e módulo (%). Além disso, temos o operador de exponenciação (**) e os operadores de incremento (++) e decremento (--).
É importante notar que o operador + também é usado para concatenação de strings. Se um dos operandos for uma string, o JavaScript converte o outro operando em string e concatena. Para garantir a adição numérica, certifique-se de que ambos os operandos são números.
let a = 10;
let b = 3;
console.log(a + b); // 13
console.log(a - b); // 7
console.log(a * b); // 30
console.log(a / b); // 3.3333...
console.log(a % b); // 1
console.log(a ** b); // 1000
// Incremento e decremento
let x = 5;
console.log(x++); // 5 (pós-incremento: retorna o valor original)
console.log(x); // 6
console.log(++x); // 7 (pré-incremento: retorna o valor incrementado)
// Cuidado com concatenação
console.log(10 + "5"); // "105"
console.log(10 - "5"); // 5 (subtração força conversão numérica)
Comparação (== vs ===)
Os operadores de comparação comparam dois valores e retornam um booleano (true ou false). Os principais são: igualdade (==), igualdade estrita (===), diferença (!=), diferença estrita (!==), maior (>), menor (<), maior ou igual (>=) e menor ou igual (<=).
A diferença entre == e === é crucial: == compara os valores após realizar coerção de tipo (conversão automática), enquanto === compara valor e tipo sem conversão. É recomendado usar === na maioria dos casos para evitar resultados inesperados.
console.log(5 == "5"); // true (coerção: string "5" vira número 5)
console.log(5 === "5"); // false (tipos diferentes)
console.log(0 == false); // true
console.log(0 === false); // false
console.log(null == undefined); // true
console.log(null === undefined); // false
// Outros exemplos
console.log(10 > 5); // true
console.log(10 <= 10); // true
console.log("a" < "b"); // true (comparação lexicográfica)
Lógicos
Os operadores lógicos são usados para combinar expressões booleanas: AND (&&), OR (||) e NOT (!). Eles seguem a lógica de curto-circuito: no &&, se o primeiro operando for false, o segundo não é avaliado; no ||, se o primeiro for true, o segundo não é avaliado. Isso é útil para atribuições condicionais.
Além disso, os operadores lógicos retornam o valor de um dos operandos, não necessariamente um booleano. Isso permite usá-los em contextos de atribuição.
let idade = 20;
let temCarteira = true;
// AND
console.log(idade >= 18 && temCarteira); // true
// OR
console.log(idade >= 18 || temCarteira); // true
// NOT
console.log(!temCarteira); // false
// Curto-circuito e retorno de valores
console.log(0 && "texto"); // 0 (primeiro falso)
console.log("texto" || "padrão"); // "texto" (primeiro verdadeiro)
console.log(null || "padrão"); // "padrão"
Operadores modernos (??, ?., spread/rest)
O operador de coalescência nula (??) retorna o operando da direita se o da esquerda for null ou undefined, caso contrário retorna o da esquerda. Diferente do ||, ele não considera outros valores falsy (como 0, "", false) como nulos.
O encadeamento opcional (?.) permite acessar propriedades de objetos de forma segura, sem lançar erro se a referência for null ou undefined. Se a expressão antes do ?. for null/undefined, a avaliação para e retorna undefined.
Os operadores spread (...) e rest (...) têm a mesma sintaxe, mas usos diferentes: spread expande elementos de um array ou objeto em outro contexto; rest agrupa argumentos em um array em funções ou desestruturação.
// Coalescência nula
let valor = 0;
console.log(valor ?? 10); // 0 (0 não é null/undefined)
console.log(valor || 10); // 10 (0 é falsy)
// Encadeamento opcional
const usuario = { nome: "João", endereco: null };
console.log(usuario.endereco?.cidade); // undefined (sem erro)
// console.log(usuario.endereco.cidade); // TypeError!
// Spread em arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5];
const combinado = [...arr1, ...arr2]; // [1,2,3,4,5]
// Spread em objetos
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, ...obj1 }; // {c:3, a:1, b:2}
// Rest em parâmetros
function soma(...numeros) {
return numeros.reduce((acc, n) => acc + n, 0);
}
console.log(soma(1, 2, 3, 4)); // 10
Precedência
A precedência de operadores determina a ordem em que as operações são avaliadas em uma expressão. Operadores com maior precedência são avaliados primeiro. A associatividade define a ordem quando operadores de mesma precedência aparecem (esquerda para direita ou direita para esquerda).
É recomendado usar parênteses para tornar a intenção clara, mesmo que você saiba a precedência. Por exemplo, a expressão 2 + 3 * 4 é avaliada como 2 + (3 * 4) = 14, pois * tem precedência maior que +.
// Precedência: multiplicação antes de adição
console.log(2 + 3 * 4); // 14
// Usando parênteses para alterar
console.log((2 + 3) * 4); // 20
// Operadores lógicos: ! > && > ||
console.log(true || false && false); // true (&& avaliado primeiro: false && false = false; depois true || false = true)
console.log((true || false) && false); // false
// Tabela resumida (do maior para menor precedência):
// 1. () (agrupamento)
// 2. !, ++, -- (unários)
// 3. *, /, %
// 4. +, -
// 5. <, <=, >, >=
// 6. ==, !=, ===, !==
// 7. &&
// 8. ||
// 9. ??
// 10. =, +=, etc. (atribuição)
Boas práticas e observações finais
Sempre prefira === e !== para comparações, a menos que você explicitamente queira a coerção de tipo. Use parênteses para tornar expressões complexas mais legíveis. O operador ?? é útil para valores default que consideram apenas null/undefined, enquanto || é mais abrangente (qualquer falsy). O encadeamento opcional é uma ferramenta poderosa para evitar erros ao acessar propriedades aninhadas de objetos que podem ser nulos.
Entender a precedência é crucial para evitar bugs sutis. Em caso de dúvida, use parênteses.
Referências
- MDN: Expressões e operadores
- MDN: Operadores aritméticos
- MDN: Operadores de comparação
- MDN: Operadores lógicos
- MDN: Operador de coalescência nula (??)
- MDN: Encadeamento opcional (?.)
- MDN: Sintaxe spread (...)
- MDN: Precedência de operadores
Exercícios
-
Qual é o resultado da expressão
10 + "5" - 2? Explique.✓ Resposta: O resultado é 103. Primeiro, a adição10 + "5"resulta em"105"(concatenação). Depois,"105" - 2converte a string para número (105) e subtrai 2, resultando em 103. -
Explique a diferença entre
==e===com exemplos.✓ Resposta:==compara valores após coerção de tipo, enquanto===compara valor e tipo sem coerção. Exemplo:5 == "5"é true, mas5 === "5"é false. -
O que o operador
??retorna? Dê um exemplo onde ele se comporta diferente de||.✓ Resposta:??retorna o operando da direita se o da esquerda fornullouundefined. Exemplo:0 ?? 10retorna 0, enquanto0 || 10retorna 10 (pois 0 é falsy). -
Usando o encadeamento opcional, como acessar a propriedade
cidadede um objetousuario.enderecoque pode sernull?✓ Resposta:usuario.endereco?.cidade. Seenderecofornullouundefined, a expressão retornaundefinedsem erro. -
Qual é a precedência dos operadores
+e*? O que a expressão2 + 3 * 4retorna?✓ Resposta: O operador*tem precedência maior que+. Portanto,2 + 3 * 4é avaliado como2 + (3 * 4) = 2 + 12 = 14.