0

I need to create array filled with objects. Lets say { foo: 0}. Then I want to add property bar to each object with different value. For example: value = index of item in array.

It looks like this

const table = new Array(10).fill({foo: 0});

for (let i = 0; i < table.length; i += 1) {
    table[i].bar = i;
}

What I expected to get is:

[
    { foo: 0, bar: 0 },
    { foo: 0, bar: 1 },
    { foo: 0, bar: 2 },
    ...
    { foo: 0, bar: 9 }
]

And what I got:

[
    { foo: 0, bar: 9 },
    { foo: 0, bar: 9 },
    { foo: 0, bar: 9 },
    ...
    { foo: 0, bar: 9 }
]

Why it behaves that way? Where I made mistake?

DEMO

EDIT To clarify

I don't want to replace objects in array with new object like table[i] = {foo: 0, bar: i}. It creates new object that replaces old one. I just want to add properties to existing object.

m51
  • 1,950
  • 16
  • 25

3 Answers3

4

Your array, has a reference to one single object. So what is happening, is that you're updating the same underlying object. If you're familiar with C, it would be like having N pointers to the same underlying object. No matter which N pointer you operate on, you will change the base underlying object.

const table = new Array(10)

for (let i = 0; i < table.length; i += 1) {
   table[i] = {foo: 0, bar: i}
}

This will create a new object for each entry in your array

Eric Yang
  • 2,678
  • 1
  • 12
  • 18
  • 1
    Ok, I got it. But I don`t want to populate array at once. I want to add new properties to existing objects in array without modifying other properties. – m51 Jul 24 '18 at 15:26
  • 2
    @kotlet Create the array as above, just remove the `bar` property. Then you can add and populate `bar` later, as expected. – Reinstate Monica Cellio Jul 24 '18 at 15:31
1

IMHO, you are looking for something like this:

const table = new Array(10);

for (let i = 0; i < table.length; i += 1) {
    table[i] = {'foo': 0, 'bar': i};
}

console.log(table)

One liner solution using ECMAScript-6:

const table = Array.from(new Array(10).keys()).map(e => ({'foo': 0, 'bar': e}))

console.log(table)
BlackBeard
  • 10,246
  • 7
  • 52
  • 62
1

Array.fill() takes a value and populates the array with it. Since non-primitives (objects, arrays) are passed by reference, modification of any item will cause the rest to change as well.

Instead, you can use Array.from() and pass the object to its mapping function:

const table = Array.from({length:10}, _ => ({foo:0}));

for (let i = 0; i < table.length; i += 1) {
    table[i].bar = i;
}

console.log(table);
Leonid Pyrlia
  • 1,594
  • 2
  • 11
  • 14