A imutabilidade é um princípio da Programação Funcional que se baseia em não alterar o estado dos dados.
No entanto, no JavaScript, as variáveis não-primitivas, tais como objetos e arrays, podem ser modificadas, mesmo quando declaradas utilizando a palavra reservada const
.
E, para aplicar a imutabilidade usando a linguagem de programação JavaScript, vamos aprender 4 maneiras de clonar objetos ao invés de modificá-los.
Operador Spread
Com este operador podemos copiar o conteúdo de um objeto ou array para uma nova variável:
const person1 = {
name: "Anne",
role: {
name: "Software Engineer"
}
}
const person2 = { ...person1 }
person2.name = "John"
console.log(person1)
// { name: "Anne", role: { name: "Software Engineer" }}
console.log(person2)
// { name: "John", role: { name: "Software Engineer" }}
Mas este operador usa uma técnica chamada Shallow cloning que basicamente clona apenas a raiz do seu objeto para poupar processamento, e para todos os subs objetos é usado a referência do objeto principal.
Isso significa que, ao alterar a propriedade role.name
do objeto person2
também vai refletir no objeto person1
:
person2.role.name = "Associate Software Engineer"
console.log(person1)
// { name: "Anne", role: { name: "Associate Software Engineer" }}
console.log(person2)
// { name: "John", role: { name: "Associate Software Engineer" }}
Para resolver isso podemos usar uma técnica chamada Deep cloning que consiste em clonar tanto o objeto raiz quanto os subs:
const person1 = {
name: "Anne",
role: {
name: "Software Engineer"
}
}
const person2 = {
...person1,
name: "John",
role: { ...person1.role }
}
person2.role.name = "Associate Software Engineer"
console.log(person2)
// { name: "John", role: { name: "Associate Software Engineer" }}
console.log(person1)
// { name: "Anne", role: { name: "Software Engineer" }}
Object.assign
Com este método podemos copiar ou mesclar o conteúdo de um ou mais objetos para uma nova variável:
const person1 = {
name: "Anne",
role: {
name: "Software Engineer"
}
}
const person2 = Object.assign({}, person1)
person2.name = "John"
console.log(person1)
// { name: "Anne", role: { name: "Software Engineer" }}
console.log(person2)
// { name: "John", role: { name: "Software Engineer" }}
Mas este método também usa a técnica Shallow cloning. Portanto, é recomendado que este método seja utilizado para clonar objetos que não tenham objetos aninhados.
Object.freeze
Já este método, além de copiar o conteúdo de um objeto para uma nova variável, também deixa as propriedades congeladas, ou seja, as propriedades não podem ser modificadas:
const person1 = {
name: "Anne",
role: {
name: "Software Engineer"
}
}
const person2 = Object.freeze(person1)
person2.name = "John"
console.log(person1)
// { name: "Anne", role: { name: "Software Engineer" }}
console.log(person2)
// { name: "Anne", role: { name: "Software Engineer" }}
Mas este método também usa a técnica Shallow cloning. Portanto, mais uma vez é recomendado que este método seja utilizado apenas para clonar objetos que não tenham objetos aninhados.
JSON.stringify e JSON.parse
O método JSON.stringify()
transforma um objeto JSON em uma string:
const person1 = {
name: "Anne",
role: {
name: "Software Engineer"
}
}
const person2Str = JSON.stringify(person1)
// '{"name":"Anne","role":{"name":"Software Engineer"}}'
Já o método JSON.parse()
transforma uma string JSON válida em um objeto e/ou array:
const person1 = {
name: "Anne",
role: {
name: "Software Engineer"
}
}
const person2Str = JSON.stringify(person1)
// '{"name":"Anne","role":{"name":"Software Engineer"}}'
const person2 = JSON.parse(person2Str)
person2.name = "John"
person2.role.name = "Associate Software Engineer"
console.log(person1)
// { name: "Anne", role: { name: "Software Engineer" }}
console.log(person2)
// { name: "John", role: { name: "Associate Software Engineer" }}
Quando o método JSON.stringify()
é acionado, ele transforma o conteúdo do objeto original em uma string JSON e as referências dos subs objetos são perdidas.
E ao usar o método JSON.parse()
todo o objeto e/ou array é recriado em memória.
Portanto, é possível clonar objetos e/ou arrays usando os métodos stringify
e parse
. Mas cuidado com seu uso pois pode ocasionar problemas de desempenho.
Conhece mais maneiras de clonar objetos no JavaScript? Deixa nos comentários 👇
Top comments (0)