1

let's look at the code:

  Test() {
let array1 = new Array(5).fill({ a: 0 })
let array2 = new Array(5).fill({ a: 0 })
for (let i = 0; i < 5; i++) {
  setTimeout(() => {
    array1[i].a = i
    array2[i] = {a:i}
    console.warn("array = ", array1)
    console.warn("array2 = ", array2)
  }, 0.2 * i)
}  

}

In this case, I wanna assign a series of values to the array1 & array2, and there are two ways to do it, which lead to totally different results. In the case array1[i].a = i, after all the code is ran, the result is array = [{a:4},{a:4},{a:4},{a:4},{a:4}], which is not what i wanted. In the second case array2[i] = {a:i}, the result will be [{a:0},{a:1},{a:2},{a:3},{a:4}] as expected. I wanna know why is it like this? What's the machanics behind this phenomenon?

Thank you.

Eric
  • 19
  • 1

1 Answers1

2

When you call .fill() and pass an object, you assign the exact same object to every element of the array. Thus, modifying a property at one array index modifies the same property at all the other indexes, because they're all pointing to the same thing.

There are a variety of ways around this issue. You could fill the array with 0 or null or some dummy value and then iterate through with .forEach(), or more simply just use an indexed for loop to initialize each element. If you initialize with { a: 0} in a for loop, a new object will be created on each iteration.

Pointy
  • 405,095
  • 59
  • 585
  • 614