Se você já leu código moderno em JavaScript — especialmente em projetos React ou Node — provavelmente encontrou sintaxes como const { nome, idade } = usuario ou ...props e ficou em dúvida sobre o que significam.
Esses são três recursos introduzidos no ES6 que mudaram completamente a forma de escrever JavaScript: desestruturação, spread e rest. Eles não adicionam nada que você não pudesse fazer antes — mas tornam o código dramaticamente mais limpo e legível.
Desestruturação de Objetos
Sem desestruturação, para extrair propriedades de um objeto você fazia assim:
const usuario = {
nome: "Fernanda",
idade: 29,
cidade: "Recife",
};
// Jeito antigo — repetitivo
const nome = usuario.nome;
const idade = usuario.idade;
const cidade = usuario.cidade;
Com desestruturação:
const { nome, idade, cidade } = usuario;
console.log(nome); // Fernanda
console.log(idade); // 29
console.log(cidade); // Recife
Muito mais limpo. Você declara as variáveis e extrai os valores do objeto em uma única linha.
Renomeando variáveis na desestruturação
E se o nome da propriedade não for um bom nome de variável, ou já existir no escopo?
const produto = {
nome: "Notebook",
preco: 3500,
};
// Renomeando: chave: novoNome
const { nome: nomeProduto, preco: valorProduto } = produto;
console.log(nomeProduto); // Notebook
console.log(valorProduto); // 3500
Valores padrão na desestruturação
Se a propriedade não existir no objeto, você pode definir um valor padrão:
const config = {
tema: "escuro",
};
const { tema, idioma = "pt-BR", notificacoes = true } = config;
console.log(tema); // escuro
console.log(idioma); // pt-BR ← valor padrão
console.log(notificacoes); // true ← valor padrão
Desestruturação em funções
Este é o uso mais comum no dia a dia — especialmente em React:
// Sem desestruturação
function exibirUsuario(usuario) {
console.log(`${usuario.nome}, ${usuario.idade} anos`);
}
// Com desestruturação no parâmetro
function exibirUsuario({ nome, idade }) {
console.log(`${nome}, ${idade} anos`);
}
exibirUsuario({ nome: "Pedro", idade: 34 }); // Pedro, 34 anos
Muito mais legível — você vê exatamente quais propriedades a função precisa.
Desestruturação de objetos aninhados
const pedido = {
id: 1042,
cliente: {
nome: "Lucia",
email: "lucia@email.com",
},
total: 450,
};
const {
id,
cliente: { nome, email },
total,
} = pedido;
console.log(id); // 1042
console.log(nome); // Lucia
console.log(email); // lucia@email.com
console.log(total); // 450
Desestruturação de Arrays
Arrays também podem ser desestruturados — a diferença é que você usa posição, não nome:
const cores = ["vermelho", "verde", "azul"];
const [primeira, segunda, terceira] = cores;
console.log(primeira); // vermelho
console.log(segunda); // verde
console.log(terceira); // azul
Você pode pular elementos usando vírgulas:
const numeros = [10, 20, 30, 40, 50];
const [primeiro, , terceiro, , quinto] = numeros;
console.log(primeiro); // 10
console.log(terceiro); // 30
console.log(quinto); // 50
Troca de variáveis com desestruturação
Um truque elegante que elimina a necessidade de uma variável temporária:
let a = 1;
let b = 2;
// Jeito antigo
let temp = a;
a = b;
b = temp;
// Com desestruturação — muito mais limpo
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1
Spread Operator — espalhando dados
O operador ... usado como spread espalha os elementos de um array ou as propriedades de um objeto:
Com arrays:
const frutas = ["maçã", "banana"];
const maisF rutas = ["laranja", "uva"];
// Combinando arrays
const todasFrutas = [...frutas, ...maisFrutas];
console.log(todasFrutas); // ["maçã", "banana", "laranja", "uva"]
// Adicionando elementos
const comKiwi = [...frutas, "kiwi"];
console.log(comKiwi); // ["maçã", "banana", "kiwi"]
// Copiando array (sem referência compartilhada)
const copia = [...frutas];
Com objetos:
const endereco = { rua: "Av. Brasil", numero: 500 };
const contato = { email: "user@email.com", telefone: "11 99999-0000" };
// Combinando objetos
const perfil = { ...endereco, ...contato };
console.log(perfil);
// { rua: "Av. Brasil", numero: 500, email: "user@email.com", telefone: "11 99999-0000" }
// Atualizando propriedades (a última prevalece em caso de conflito)
const usuarioAtualizado = { ...endereco, numero: 750, complemento: "apto 12" };
console.log(usuarioAtualizado);
// { rua: "Av. Brasil", numero: 750, complemento: "apto 12" }
Esse padrão de atualizar objetos com spread é essencial no React.
Spread em chamadas de função
const numeros = [5, 2, 8, 1, 9, 3];
// Math.max não aceita array — aceita argumentos separados
console.log(Math.max(...numeros)); // 9
console.log(Math.min(...numeros)); // 1
function somar(a, b, c) {
return a + b + c;
}
const valores = [10, 20, 30];
console.log(somar(...valores)); // 60
Rest Operator — coletando o resto
O mesmo símbolo ... mas com papel oposto: em vez de espalhar, ele coleta múltiplos elementos em um único array ou objeto.
Em funções — quantidade variável de argumentos:
function somar(...numeros) {
return numeros.reduce((acc, n) => acc + n, 0);
}
console.log(somar(1, 2)); // 3
console.log(somar(1, 2, 3, 4, 5)); // 15
console.log(somar(10, 20)); // 30
numeros é um array com todos os argumentos passados — independente de quantos forem.
Misturando parâmetros normais com rest:
function criarTime(capitao, ...jogadores) {
console.log(`Capitão: ${capitao}`);
console.log(`Jogadores: ${jogadores.join(", ")}`);
}
criarTime("Carlos", "Ana", "Pedro", "Lucia", "Marcos");
// Capitão: Carlos
// Jogadores: Ana, Pedro, Lucia, Marcos
O rest deve ser sempre o último parâmetro.
Rest na desestruturação
const { nome, idade, ...resto } = {
nome: "Rafael",
idade: 27,
cidade: "Salvador",
profissao: "Designer",
ativo: true,
};
console.log(nome); // Rafael
console.log(idade); // 27
console.log(resto); // { cidade: "Salvador", profissao: "Designer", ativo: true }
Extremamente útil para separar o que você precisa do que você quer repassar adiante.
Com arrays:
const [primeiro, segundo, ...demais] = [10, 20, 30, 40, 50];
console.log(primeiro); // 10
console.log(segundo); // 20
console.log(demais); // [30, 40, 50]
Exemplo completo — tudo junto
Veja como esses três recursos se combinam em um cenário real:
const pedidos = [
{ id: 1, cliente: "Ana", total: 150, status: "pago" },
{ id: 2, cliente: "Bruno", total: 320, status: "pendente" },
{ id: 3, cliente: "Clara", total: 80, status: "pago" },
];
// Função que recebe um pedido, extrai o que precisa e retorna um resumo
function resumirPedido({ id, cliente, total, ...extras }) {
return {
resumo: `Pedido #${id} — ${cliente}: R$ ${total}`,
detalhes: { ...extras },
};
}
pedidos
.filter(({ status }) => status === "pago")
.map(resumirPedido)
.forEach(({ resumo, detalhes }) => {
console.log(resumo);
console.log("Detalhes:", detalhes);
});
// Pedido #1 — Ana: R$ 150
// Detalhes: { status: "pago" }
// Pedido #3 — Clara: R$ 80
// Detalhes: { status: "pago" }
Resumo visual
| Recurso | Sintaxe | O que faz |
|---|---|---|
| Desestruturação de objeto | const { a, b } = obj |
Extrai propriedades em variáveis |
| Desestruturação de array | const [x, y] = arr |
Extrai elementos por posição |
| Spread em array | [...arr1, ...arr2] |
Espalha elementos |
| Spread em objeto | { ...obj1, ...obj2 } |
Espalha propriedades |
| Rest em função | function f(...args) |
Coleta argumentos em array |
| Rest em desestruturação | const { a, ...resto } = obj |
Coleta o restante |
Tarefa para você
const funcionarios = [
{ id: 1, nome: "Joana", cargo: "Dev", salario: 5000, ativo: true },
{ id: 2, nome: "Marcos", cargo: "Design", salario: 4000, ativo: false },
{ id: 3, nome: "Silvia", cargo: "Dev", salario: 5500, ativo: true },
];
// 1. Use desestruturação para extrair nome e salario do primeiro funcionário
// 2. Crie um novo array com todos os funcionários mais um novo:
// { id: 4, nome: "Lucas", cargo: "QA", salario: 4500, ativo: true }
// 3. Crie uma função que receba um funcionário via desestruturação
// e retorne: "Joana (Dev) — R$ 5000"
// 4. Separe os dados de identidade (id, nome) do restante usando rest
Conclusão
Neste artigo você aprendeu:
- Desestruturação de objetos com renomeação e valores padrão
- Desestruturação de arrays por posição
- Desestruturação em parâmetros de função
- Spread para combinar e copiar arrays e objetos
- Rest para coletar argumentos e restos de desestruturação
- Como esses três recursos se combinam em código real
No próximo artigo vamos explorar um dos temas mais incompreendidos do JavaScript: escopo, hoisting e closures — conceitos que explicam como o JS gerencia suas variáveis nos bastidores.
📚 Fontes e Referências
- MDN Web Docs — Desestruturação: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
- MDN Web Docs — Spread Syntax: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Spread_syntax
- MDN Web Docs — Rest Parameters: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Functions/rest_parameters
- JavaScript.info — Destructuring: https://javascript.info/destructuring-assignment
- JavaScript.info — Spread and Rest: https://javascript.info/rest-parameters-spread
- Eloquent JavaScript, Cap. 4 — Data Structures: https://eloquentjavascript.net/04_data.html
- You Don't Know JS: ES6 & Beyond — Kyle Simpson: https://github.com/getify/You-Dont-Know-JS
- Airbnb JavaScript Style Guide — Destructuring: https://github.com/airbnb/javascript#destructuring