Conhecendo o structuredClone
Tags: javascript, braziliandevs, frontend
Published: 2022-07-30 01:23:37

Mais um artigo da _(quem sabe vire uma)_ série: "Conhecendo"! 😄 O tema da vez é um método muuuito útil que foi incorporado nos navegadores, o **structuredClone**.

Mas antes de falar dele, vamos entender um pouco sobre _shallow copy_ e _deep copy_.

---

Pra começar, vamos criar um objeto e colocar alguns valores:
```
const objetoOriginal = {
    a: 'valor1',
    b: 'valor2',
    c: {
        d: 'valor3',
    }
};
```

Quando executamos esse código, o javascript vai armazenar esses valores em memória e vai criar uma referência a esse endereço de memória para que possamos alterar e acessar quando necessário.

![Diagrama básico do armazenamento de objeto](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rc8y3otwjl1loyv7pqlk.png)

Agora, se fizermos uma cópia simples (_shallow copy_), estaremos fazendo uma cópia dessa **referência**, e não do valor que está lá na memória.

Então quando fazemos isso:
```
const objetoNovo = objetoOriginal;
```

Por baixo dos panos o que vai acontecer é:
![Diagrama báico de um shallow copy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szlwqmm11dcz96qvjdyu.png)

Isso acontece porque o _shallow copy_ é, bem como o nome diz, apenas uma cópia superficial. Dessa forma, se alteramos algum valor no **objetoNovo**, essa alteração pode acabar refletindo no **objetoOriginal** e dependendo da situação pode causar muitos problemas.

Já no _deep copy_ a cópia é feita por completo, criando um novo endereço em memória para armazenar o novo objeto.

![Diagrama báico de um deep copy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4p7tc3szl9vpgfoyyptu.png)

Dessa forma podemos alterar a cópia livremente, sem risco de causar algum efeito colateral indesejado.

Esse tipo de cópia costuma ser um pouco mais custosa, muitas vezes sendo feita manualmente ou utilizando alguma biblioteca externa, como o [lodash](https://lodash.com/).

---

Voltemos agora à nossa estrela de hoje: o **structuredClone**!

A sintaxe do _structuredClone_ é super simples. Basta passar qual a variável a ser copiada, e será retornado uma cópia completa do que foi passado. Mesmo se for um objeto complexo, com vários níveis, tudo será espelhado.
```
const objetoClone = structuredClone(objetoOriginal);
```

Simples assim! 🤩 Não precisamos nem importar nada.

Internamente, o _structuredClone_ implementa um [algoritmo de cópia](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) recursiva, que também dá suporte a referências circulares.

Como parâmetro, podemos passar _quaaase_ qualquer tipo de variável. Caso o valor que você tente clonar não seja copiável, será disparado um erro do tipo **DataCloneError**.

Também temos um segundo parâmetro opcional, que recebe uma lista e nos permite **transferir** valores. Fazendo com que passem a existir apenas na cópia e não mais no original.

 **Mas atenção**: Não é qualquer valor que pode ser movido. Apenas objetos dos tipos chamados de [_Transferable_](https://developer.mozilla.org/en-US/docs/Glossary/Transferable_objects) podem ser passados nesse parâmetro, entram nessa lista os _Buffers_, _Streams_, etc... Mas isso é assunto pra um outro artigo 😉

Em aplicações com bastante manipulação de dados, o _structuredClone_ é extremamente útil! Prático de usar, reduz dependências, além de já ter [bastante suporte entre os navegadores](https://caniuse.com/mdn-api_structuredclone), então pode usar sem medo!

## Quer ver mais a fundo sobre o _structuredClone_?

Então dá uma olhada [nessa página da MDN](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone), ou veja diretamente a [especificação](https://html.spec.whatwg.org/multipage/structured-data.html)!

---
E você, já conhecia o _structuredClone_? Faz cópias de alguma forma diferente? Comenta aqui! 😁