Cópia profunda de objetos em JavaScript: top 5 maneiras

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: Por que a cópia comum não funciona?

\n\n

Imagine: você está escrevendo um aplicativo que processa uma configuração complexa de usuário. Você faz const newConfig = oldConfig, altera alguns campos — e de repente o objeto original também muda. Dor familiar? 👋

\n\n

Em JavaScript, objetos são passados por referência. Isso significa que uma simples operação de atribuição não cria um novo objeto, apenas copia o ponteiro para o antigo. Daí surge a principal questão que atormenta milhares de desenvolvedores no Stack Overflow: "What is the most efficient way to deep clone an object in JavaScript?".

\n\n

Neste artigo, vamos analisar todas as maneiras populares de cópia profunda, seus prós, contras e desempenho. Você descobrirá qual método escolher para 2024 e aprenderá a escrever seu próprio deep clone confiável.

\n\n

Por que estamos falando sobre cópia profunda?

\n\n

A cópia profunda (deep clone) cria uma cópia totalmente independente do objeto com todas as estruturas aninhadas. Ao contrário da cópia superficial (shallow copy), onde objetos aninhados permanecem compartilhados.

\n\n

Aqui está um cenário típico onde isso é necessário:

\n
    \n
  • Trabalho com Redux / Zustand: não é possível mutar o estado, é necessário criar cópias.
  • \n
  • Serialização de dados para envio ao servidor.
  • \n
  • Trabalho com cache ou configurações que não podem ser alteradas.
  • \n
  • Testes unitários: para não afetar os dados originais.
  • \n
\n\n

Mas não é tão simples. Se você tentar copiar um objeto com funções, undefined, Symbol ou referências cíclicas — muitos métodos falharão ou perderão dados. Vamos analisar cada método detalhadamente.

\n\n

Método 1: JSON.parse(JSON.stringify(obj)) — antigo, mas funcional

\n\n

Esta é a maneira mais popular entre iniciantes. É simples e rápido de escrever:

\n\n
const original = {\n    name: "Анна",\n    age: 25,\n    address: { city: "Москва", zip: 101000 },\n    hobbies: ["чтение", "бег"]\n};\n\nconst clone = JSON.parse(JSON.stringify(original));\n\nclone.address.city = "Санкт-Петербург";\nconsole.log(original.address.city); // "Москва" — ✅ cópia independente!\n
\n\n

Prós:

\n
    \n
  • 🔥 Sintaxe muito simples.
  • \n
  • 🔥 Funciona para a maioria dos casos simples.
  • \n
\n\n

Contras (críticos!):

\n
    \n
  • ❌ Perde funções — elas se transformam em undefined.
  • \n
  • ❌ Perde undefined — campos com valor undefined desaparecem.
  • \n
  • ❌ Perde Symbol — chaves-símbolo desaparecem.
  • \n
  • ❌ Não funciona com referências cíclicas — lança erro TypeError.
  • \n
  • ❌ Problemas com datas — Date se transforma em string.
  • \n
  • ❌ Problemas com Map, Set, RegExp — eles se tornam objetos vazios.
  • \n
\n\n

Conclusão: Adequado apenas para dados que são garantidamente serializáveis em JSON (strings, números, arrays, objetos simples).

\n\n

Método 2: Structured Clone API — padrão moderno (2024)

\n\n

A partir de 2022, o JavaScript ganhou uma maneira nativa de fazer cópia profunda — structuredClone. Está disponível em todos os navegadores modernos e Node.js 17+.

\n\n
const clone = structuredClone(original);\n\nclone.address.city = "Казань";\nconsole.log(original.address.city); // "Москва" — ✅\n
\n\n

O que o structuredClone pode fazer:

\n
    \n
  • ✅ Referências cíclicas — funciona!
  • \n
  • ✅ Datas — preserva o tipo Date.
  • \n
  • ✅ Map e Set — copia corretamente.
  • \n
  • ✅ RegExp — também funciona.
  • \n
  • ✅ ArrayBuffer e Ty
  • \n

Blogs

Book Recommendations