Neste post, encontrará 3 formas fáceis de realizar clonagem rasa (também conhecida como cópia) de objectos em JavaScript.
Como bónus, vou mostrar como pode também actualizar, adicionar, ou remover propriedades no lugar do clone. Isso é útil quando se pretende realizar uma actualização sobre o objecto de uma forma imutável.
Nota
As 3 formas de clonar objectos descritas neste post executam uma cópia superficial.
Uma cópia rasa significa que apenas o objecto real é copiado. Se o objecto copiado contiver objectos aninhados – estes objectos aninhados não são clonados.
Table of Contents
- 1. Clonagem usando propagação de objectos
- 2. Clonagem usando repouso de objectos
- 3. Clonagem usando Object.assign()
- 4. Resumo
1. Clonagem usando propagação de objectos
A forma mais simples de clonar um objecto JavaScript simples é invocar o operador de propagação de objectos:
const clone = { ...object};
Onde object
é o objecto que gostaria de copiar, e clone
é a cópia rasa de object
.
Por exemplo, vamos criar uma cópia rasa de hero
objecto:
const hero = { name: 'Batman', city: 'Gotham'};const heroClone = { ...hero};heroClone; // { name: 'Batman', city: 'Gotham' }hero === heroClone; // => false
heroClone
é um objecto clone de hero
, o que significa que contém todas as propriedades de hero
.
hero === heroClone
avalia a false
hero
e heroClone
são, no entanto, instâncias de objectos diferentes.
1.1 Bónus de propagação de objectos: adicionar ou actualizar adereços clonados
Um benefício imediato da utilização de propagação de objectos é que pode actualizar ou adicionar novas propriedades ao objecto clonado no local, se precisar dele.
Clonemos o hero
objecto, mas actualize name
propriedade a um valor diferente e adicione uma nova propriedade realName
:
const hero = { name: 'Batman', city: 'Gotham'};const heroEnhancedClone = { ...hero, name: 'Batman Clone', realName: 'Bruce Wayne'};heroEnhancedClone; // { name: 'Batman Clone', city: 'Gotham', realName: 'Bruce Wayne' }
2. Clonagem usando repouso de objectos
Outra boa maneira de clonar objectos rasos é usando o operador de repouso de objectos:
const { ...clone } = object;
Again, vamos usar o operador de repouso para fazer uma cópia de hero
objecto:
const hero = { name: 'Batman', city: 'Gotham'};const { ...heroClone } = hero;heroClone; // { name: 'Batman', city: 'Gotham' }hero === heroClone; // => false
Após aplicar o operador de descanso const { ...heroClone } = hero
, o heroClone
variável contém uma cópia de hero
objecto.
2.1 Bónus de repouso do objecto: saltar adereços clonados
Um bom bónus ao usar repouso do objecto é a capacidade de saltar certas propriedades ao clonar.
Por exemplo, vamos criar um clone de hero
objecto, mas saltar city
propriedade no clone:
const hero = { name: 'Batman', city: 'Gotham'};const { city, ...heroClone } = hero;heroClone; // { name: 'Batman' }
2.2 Super bónus: a combinação de propagação e repouso do objecto
Aumento de propagação traz o bónus de actualização ou adição de novas propriedades, enquanto o repouso do objecto tem o benefício de saltar propriedades no clone resultante.
P>Pode combinar propagação e repouso de objectos numa única afirmação para herdar todos estes benefícios? Sim, pode!
P>Vamos clonar o hero
objecto, adicionando também uma nova propriedade realName
e saltando a propriedade city
:
const hero = { name: 'Batman', city: 'Gotham'};const { city, ...heroClone } = { ...hero, realName: 'Bruce Wayne'};heroClone; // { name: 'Batman', realName: 'Bruce Wayne' }
Combinar o objecto espalhado e descansar para clonar objectos e realizar manipulação de propriedades numa única afirmação é óptimo!
3. clonagem usando Objecto.assign()
Finalmente, Object.assign(target, ...sources)
vamos formar o mesmo objecto clone:
const clone = Object.assign({}, object);
Object.assign()
na prática e criar um objecto clone de hero
objecto:
const hero = { name: 'Batman', city: 'Gotham'};const heroClone = Object.assign({}, hero);heroClone; // { name: 'Batman', city: 'Gotham' }hero === heroClone; // => false
Object.assign({}, hero)
cria um clone de hero
objecto através da fusão do segundo argumento hero
no primeiro argumento {}
.
3.1 Object.assign() bonus: adicionar ou actualizar adereços clonados
Object.assign()
permite também actualizar ou adicionar novas propriedades ao clone.
P>Vamos copiar o hero
objecto, mas ao mesmo tempo actualizar name
propriedade:
const hero = { name: 'Batman', city: 'Gotham'};const heroClone = Object.assign({}, hero, { name: 'Batman Clone' });heroClone; // { name: 'Batman Clone', city: 'Gotham' }
Object.assign({}, hero, { name: 'Batman Clone' })
cria o objecto em 2 passos.
primeiro, o segundo argumento hero
é fundido no primeiro argumento {}
. Isto equivale a { name: 'Batman', city: 'Gotham' }
.
Segundo, o terceiro argumento { name: 'Batman Clone' }
é fundido no resultado do passo anterior, substituindo a propriedade name
. Finalmente, obtém-se o objecto { name: 'Batman Clone', city: 'Gotham' }
.
4. Resumo
JavaScript fornece 3 boas maneiras de clonar objectos: usando o operador de propagação, operador de repouso e Object.assign()
função.
Lado de apenas clonar objectos, usando o operador de propagação e Object.assign()
permite adicionar ou actualizar propriedades ao criar o clone.
O operador de teste também dá o benefício de saltar certas propriedades ao clonar.
E o que é óptimo, pode combinar a propagação e o repouso do objecto numa única afirmação, para que possa clonar o objecto, e ao mesmo tempo adicionar, actualizar ou saltar propriedades de ser clonado.
Isso é útil se quiser abraçar a imutabilidade e ser capaz de manipular as propriedades do objecto clonado no lugar.
Que outras boas formas de clonar objectos em JavaScript conhece?