Copiar objetos "de verdade" em JavaScript sempre exigiu gambiarras: espalhar propriedades com { ...obj } só copia um nível, e o truque JSON.parse(JSON.stringify(obj)) quebra silenciosamente com Date, Map, Set, referências circulares e mais. A função global structuredClone() resolve isso de forma nativa, criando uma cópia profunda de um valor usando o mesmo algoritmo que o navegador já usava internamente para postMessage().
O problema com as alternativas antigas
const original = {
nome: 'Pedido #42',
criadoEm: new Date(),
tags: new Set(['urgente', 'online']),
};
const copia = JSON.parse(JSON.stringify(original));
console.log(copia.criadoEm); // string, não é mais um Date!
console.log(copia.tags); // {} — o Set virou um objeto vazio
O JSON.stringify() só entende os tipos que existem em JSON: perde Date, Map, Set, RegExp, ArrayBuffer, e lança erro em referências circulares.
Como usar o structuredClone
A função recebe o valor a ser clonado e devolve uma cópia profunda e independente, preservando os tipos:
const original = {
nome: 'Pedido #42',
criadoEm: new Date(),
tags: new Set(['urgente', 'online']),
};
const copia = structuredClone(original);
console.log(copia.criadoEm instanceof Date); // true
console.log(copia.tags instanceof Set); // true
console.log(copia.tags.has('urgente')); // true
copia.tags.add('nova-tag');
console.log(original.tags.has('nova-tag')); // false — são independentes
Referências circulares funcionam de verdade
Diferente do JSON.stringify(), que lança TypeError: Converting circular structure to JSON, o algoritmo de clonagem estruturada lida naturalmente com ciclos:
const no = { valor: 1 };
no.proprio = no; // referência circular
const copiaDoNo = structuredClone(no);
console.log(copiaDoNo.proprio === copiaDoNo); // true
console.log(copiaDoNo === no); // false
Transferindo em vez de copiar
Alguns objetos, como ArrayBuffer, podem ser transferidos em vez de copiados através do segundo argumento, o que move a posse da memória sem duplicá-la:
const buffer = new ArrayBuffer(1024);
const clone = structuredClone(buffer, { transfer: [buffer] });
console.log(buffer.byteLength); // 0 — foi esvaziado, não copiado
console.log(clone.byteLength); // 1024
Quando usar
- Duplicar estado antes de modificá-lo, evitando mutar objetos compartilhados (ex: estado de formulários, snapshots para "desfazer").
- Clonar dados que envolvem
Date,Map,SetouArrayBuffer, onde o truque do JSON falha. - Passar dados para Web Workers, já que o mesmo algoritmo é usado por baixo dos panos em
postMessage(). - Guardar uma cópia "congelada no tempo" de um objeto antes de uma operação assíncrona que pode demorar.
O que não dá para clonar
Nem tudo pode passar pelo algoritmo de clonagem estruturada. Tentar clonar function, elementos do DOM ou objetos com métodos de get/set especiais lança um DataCloneError:
function exemplo() {}
try {
structuredClone(exemplo);
} catch (erro) {
console.log(erro.name); // "DataCloneError"
}
Além disso, protótipos personalizados não são preservados: o clone de uma instância de classe vira um objeto simples, perdendo os métodos do protótipo original.
Compatibilidade
O structuredClone() é Baseline e tem suporte em todos os navegadores modernos e no Node.js desde a versão 17. Ainda vale checar a versão mínima do runtime em projetos que precisam suportar ambientes mais antigos.
Conclusão
O structuredClone() substitui de vez o truque frágil do JSON.parse(JSON.stringify()) para cópias profundas, preservando tipos complexos e lidando corretamente com ciclos, sem precisar de nenhuma biblioteca externa.
0 Comentário
Deixe seu Comentário!
Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.