Problema com cópia de objeto em Javascript

Alguém poderia me explicar porque isso acontece?
Veja bem, eu tenho uma variável b que um array de objetos, meu objetivo aqui é copiar este array de objetos para a variável a e posteriormente quero fazer alterações em a, mas quero que b continue sem alteração alguma. Mas por que isso abaixo acontece, isto é, b é alterado também?

> let a = []
undefined
> let b = [{name: 'Yuri Melo'}, {name: 'Igor'}, {name: 'Iran Melo'}]
undefined
> b
[ { name: 'Yuri Melo' }, { name: 'Igor' }, { name: 'Iran Melo' } ]
> a[0] = b[0]
{ name: 'Yuri Melo' }
> a
[ { name: 'Yuri Melo' } ]
> b
[ { name: 'Yuri Melo' }, { name: 'Igor' }, { name: 'Iran Melo' } ]
> a[0]['name'] = [a[0]['name']]
[ 'Yuri Melo' ]
> a
[ { name: [ 'Yuri Melo' ] } ]
> b
[ { name: [ 'Yuri Melo' ] }, { name: 'Igor' }, { name: 'Iran Melo' } ]
>

Isso se chama Assignment by reference, quando voce cria a variavel b do tipo array/objeto/funcao e coloca os valores, la na memoria voce esta criando uma unidade de referencia, um espaco dedicado ao b, no entanto quando voce cria e assina o a ao mesmo valor que o b ja tem reservado na memoria, ao inves de uma copia, o que acontece é que uma referencia é criada nos mesmos slots ja ocupados pelo b, entao nesse momento a e b apontam para o mesmo local na memoria.

Pesquise por value vs reference para voce entender mais.
Unidades primitivas como undefined, null, boolean, number, ou string sao assinadas por value, enquanto unidades como Array, Function e Objects sao por referencia.

Aqui esta alguns materiais para voce entender melhor o que esta acontecendo:
heap memory allocation by reference wikipedia
value vs reference reading material
value vs reference youtube lesson

EDIT: Eu expliquei o que esta acontecendo mas acabei esquecendo de te dar a solucao. Entao para concluir esse exercicio voce precisa realizar a alteracao sem se preocupar com a referencia voce precisa entender que o metodo disponivel no Array.prototype.slice() faz uma shallow copy da lista original, ou seja, voce ainda continua mantendo a referencia de b para o a, entao para resolver isso voce precisa de fazer uma deep copy do b e extrair o 0th index atraves da serializacao. Como por exemplo:

let a = JSON.parse(JSON.stringify(b))[0];

Agora sim voce pode continuar a alteracao:

    let a = [];
    let b = [{name: 'Yuri Melo'}, {name: 'Igor'}, {name: 'Iran Melo'}];

    a[0] = JSON.parse(JSON.stringify(b))[0];

    console.log(a, 'before');
    console.log(b, 'before');

    a[0]['name'] = [a[0]['name']];

    console.log(a, 'after');
    console.log(b, 'after');
1 curtida

Que foooodaaa!! Sendo bem sincero, eu não sabia disso. Cara, muito obrigado. Você não quebrou um galho, mas sim uma árvore inteira kkkkk. Muito obrigado mesmo.

1 curtida

De nada! Boa sorte :wink:

1 curtida