structuredClone(): Clonagem Profunda Nativa em JavaScript

Como a função global structuredClone() cria cópias profundas de objetos preservando Date, Map, Set e referências circulares, substituindo o truque frágil de JSON.parse(JSON.stringify()).

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

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.

caniuse

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.

Tecnologia:
js

Deixe seu Comentário!

Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.

Comentário
Nome
Email
lock Seu e-mail não será publicado.