0

i recently came into a weird(for me) behaviour.

 let test = [
    { id: 1, name: 'test1' },
    { id: 2, name: 'test2' },
    { id: 3, name: 'test3' }
]
let test2 = []
test.forEach((elem, index) => {

    console.warn(elem, index);
    test2.push(elem.name)
    elem.arr = test2
})

console.warn(test);

and i want the expected outcome to be like this

[ { id: 1, name: 'test1', arr: [ 'test1'] },
  { id: 2, name: 'test2', arr: [ 'test1', 'test2'] },
  { id: 3, name: 'test3', arr: [ 'test1', 'test2', 'test3' ] }]

but i get this

[ { id: 1, name: 'test1', arr: [ 'test1', 'test2', 'test3'] },
  { id: 2, name: 'test2', arr: [ 'test1', 'test2', 'test3'] },
  { id: 3, name: 'test3', arr: [ 'test1', 'test2', 'test3'] }]

Can someone explain me why this is happening(probably something about references?) and a solution?

maazadeeb
  • 5,922
  • 2
  • 27
  • 40
AnHa
  • 130
  • 1
  • 7

3 Answers3

3

There's only a single test2 array, referred to (via the arr) property three times in a row. All of these entries point back to a single array.

You probably wanted to take a copy:

elem.arr = [...test2]

let test = [
    { id: 1, name: 'test1' },
    { id: 2, name: 'test2' },
    { id: 3, name: 'test3' }
]
let test2 = []
test.forEach((elem, index) => {

    //console.log(elem, index);
    test2.push(elem.name)
    elem.arr = [...test2]
})

console.log(JSON.stringify(test, null, 2));
spender
  • 117,338
  • 33
  • 229
  • 351
1

I believe what's happening is that the arr attribute for each element is being set equal to the test2 reference, rather than copying in the contents of test2 at that time.

More information here: Is JavaScript a pass-by-reference or pass-by-value language?

See also: Copy array by value

Based on the second link, you need to create new arrays when assigning to elem.arr.

elem.arr = test2.slice();

[Update] @spender had a newer way to copy arrays I didn't know about (still catching up on ES6). See also: https://www.samanthaming.com/tidbits/35-es6-way-to-clone-an-array

cdpautsch
  • 1,769
  • 3
  • 13
  • 24
1

probably something about references?

You are correct. The assignment does not make a copy of the value of test2 into elem.arr So after the operation is done. If you try to run test2 = [] All the arr property will be []

If you wish to do so you can destructure just like spender's answer

Nikko Khresna
  • 1,024
  • 8
  • 10