Operadores em JavaScript
Esta aula cobre os operadores em JavaScript, incluindo aritméticos, comparação (com foco na diferença entre == e ===), lógicos, operadores modernos (??, ?., spread/rest) e precedência. São apresentados exemplos práticos e exercícios para fixação.
Operadores são fundamentais em qualquer linguagem de programação, pois permitem realizar operações sobre valores e variáveis. Em JavaScript, os operadores são usados para cálculos aritméticos, comparações, lógica booleana, atribuições e manipulações mais avançadas. Nesta aula, exploraremos os principais tipos de operadores, com destaque para nuances importantes como a diferença entre igualdade solta e estrita, e os operadores modernos introduzidos no ES6 e posteriores.
Dominar os operadores é essencial para escrever código expressivo, conciso e correto. Vamos mergulhar em cada categoria com exemplos práticos.
Aritméticos
Os operadores aritméticos são usados para realizar operações matemáticas em números. JavaScript fornece os operadores básicos: adição (+), subtração (-), multiplicação (*), divisão (/) e o resto da divisão (%). Além disso, existem os operadores de incremento (++) e decremento (--), que são unários.
Importante notar que o operador + também é usado para concatenação de strings. Se um dos operandos for uma string, o outro é convertido em string e concatenado. Já os demais operadores aritméticos tentam converter strings em números.
// Operadores aritméticos básicos
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.333...
console.log(a % b); // 1 (resto)
// Incremento e decremento
let contador = 0;
contador++; // pós-incremento: retorna 0, depois incrementa
console.log(contador); // 1
++contador; // pré-incremento: incrementa e retorna 2
console.log(contador); // 2
// Concatenação com +
console.log(5 + '5'); // "55" (string)
console.log('5' - 3); // 2 (número, pois - força conversão)
Comparação (== vs ===)
Operadores de comparação retornam um valor booleano (true ou false). Os principais são: igualdade solta (==), igualdade estrita (===), desigualdade solta (!=), desigualdade estrita (!==), maior (>), menor (<), maior ou igual (>=) e menor ou igual (<=).
A diferença crucial entre == e === é que == realiza coerção de tipo antes da comparação, enquanto === compara valor e tipo sem coerção. É recomendado usar === sempre para evitar resultados inesperados.
// Exemplos de comparação
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 (false é convertido para 0)
console.log(0 === false); // false
console.log(null == undefined); // true (regra especial)
console.log(null === undefined); // false
// Comparações numéricas
console.log(10 > 5); // true
console.log(10 <= 10); // true
Lógicos
Operadores lógicos combinam expressões booleanas: && (AND lógico), || (OR lógico) e ! (NOT lógico). Eles são frequentemente usados em condicionais e também podem ser usados para atribuição de valores com curto-circuito.
No JavaScript, os operadores lógicos funcionam com curto-circuito: no &&, se o primeiro operando for falsy, o segundo não é avaliado; no ||, se o primeiro for truthy, o segundo é ignorado. Eles retornam o valor de um dos operandos (não necessariamente booleano).
// Operadores lógicos
let idade = 25;
let temCarteira = true;
// AND lógico
if (idade >= 18 && temCarteira) {
console.log('Pode dirigir');
}
// OR lógico
let nome = '';
let apelido = 'João';
let nomeExibido = nome || apelido; // 'João'
console.log(nomeExibido);
// NOT lógico
let ativo = false;
console.log(!ativo); // true
// Curto-circuito com &&
let usuario = { nome: 'Maria' };
usuario && console.log(usuario.nome); // 'Maria'
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 ou '' como nulos.
O operador de encadeamento opcional (?.) permite acessar propriedades de um objeto de forma segura, sem lançar erro se uma propriedade intermediária for null ou undefined. Spread (...) expande arrays/objetos, enquanto rest (...) agrupa argumentos em um array.
// Coalescência nula (??)
let valor = 0;
let resultado = valor ?? 'padrão'; // 0 (porque 0 não é null/undefined)
console.log(resultado);
let nulo = null;
let resultado2 = nulo ?? 'padrão'; // 'padrão'
console.log(resultado2);
// Encadeamento opcional (?.)
const pessoa = { endereco: { rua: 'Rua A' } };
console.log(pessoa.endereco?.rua); // 'Rua A'
console.log(pessoa.contato?.email); // undefined (sem erro)
// Spread com arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinado = [...arr1, ...arr2]; // [1,2,3,4,5,6]
// Rest em parâmetros
function somar(...numeros) {
return numeros.reduce((acc, n) => acc + n, 0);
}
console.log(somar(1, 2, 3)); // 6
Precedência
Precedência de operadores determina a ordem em que as operações são avaliadas. Operadores com maior precedência são avaliados primeiro. Por exemplo, multiplicação tem precedência maior que adição. Parênteses podem ser usados para forçar uma ordem específica.
É importante conhecer a precedência para evitar bugs. Uma tabela completa está disponível na MDN. Aqui estão alguns exemplos:
// Precedência: multiplicação antes de adição
let resultado = 2 + 3 * 4; // 14 (3*4=12, +2=14)
console.log(resultado);
// Parênteses alteram a ordem
let resultado2 = (2 + 3) * 4; // 20
console.log(resultado2);
// Operadores lógicos: ! tem maior precedência, depois &&, depois ||
let a = true;
let b = false;
let c = true;
console.log(a || b && c); // true (b && c é false, a || false = true)
console.log((a || b) && c); // true (a || b = true, true && c = true)
Boas práticas e observações finais
Sempre prefira === e !== em vez de == e != para evitar coerção implícita. Use ?? para valores nulos/undefined, e ?. para acessos seguros. Use parênteses para tornar a precedência explícita e melhorar a legibilidade. Evite cadeias muito longas de operadores lógicos sem parênteses.
Referências
- MDN: Expressões e Operadores
- MDN: Precedência de Operadores
- MDN: Operador de coalescência nula (??)
- MDN: Encadeamento opcional (?.)
- MDN: Spread syntax (...)
- MDN: Operadores de comparação
Exercícios
- Qual é a saída do código:
console.log(10 + '10');? Explique. - Diferencie == e === com um exemplo prático.
- O que o operador ?? retorna no código:
let x = 0 ?? 'padrão';? Por quê? - Usando encadeamento opcional, como acessar a propriedade
emailde um objetouserque pode ser null sem causar erro? - Qual a ordem de avaliação da expressão
true || false && false? Use parênteses para tornar explícito.
5 == '5' retorna true (coerção de tipo), enquanto 5 === '5' retorna false (tipos diferentes).user?.email retorna undefined se user for null/undefined, sem lançar erro.true || (false && false) => true || false => true.