0

I have an array of objects and assigned their properties and values using Array.prototype.fill(). I want to assign a new value to a property of a specific element in the array.

For example:

let data = Array(3).fill({test_1: 0, test_2: true});

function f(index) {
    data[index].test_1 = 5;
    console.log(data);
}

f(0);

However, instead of assigning that value to that specific object's property, all of the objects in the array have their own property assigned that same value.

Here is the output:

// Actual result
[
 {
  test_1: 5,
  test_2: true
 },
 {
  test_1: 5,
  test_2: true
 },
 {
  test_1: 5,
  test_2: true
 }
];

// Expected result
[
 {
  test_1: 5,
  test_2: true
 },
 {
  test_1: 0,
  test_2: true
 },
 {
  test_1: 0,
  test_2: true
 }
];

Instead of only the first object getting 5 as its value for the test_1 property, all three objects have 5 as their value for their test_1 properties.

So, my questions are:

  • Why is f() assigning the same value to the same property of all the elements in the array?
  • How can I assign a value to a property of only a specific element of the array?
J.M.
  • 3
  • 2
  • You are passing an Object to `fill`, so `fill` will put that exact object at every index. They're all references to the only Object you created – blex May 28 '21 at 21:54
  • "*all three objects have 5 as their value*" - no, there is only one object. – Bergi May 28 '21 at 22:21

2 Answers2

1

Do not use Array.fill unless you want to fill it with primitive types.

By this let data = Array(3).fill({test_1: 0, test_2: true}) you passing same object every time, so your array contains 3 times same object, then if you modifying any element of array, in fact it's the same object modified by reference. To avoid it use Array.from syntax combined with map callback. Like this:

let data = Array.from({length: 3},  _ => ({test_1: 0, test_2: true}))

function f(index) {
    data[index].test_1 = 5;
    console.log(data);
}

f(0)
.as-console-wrapper { max-height: 100% !important; top: 0; }
ulou
  • 5,542
  • 5
  • 37
  • 47
0

Since everyone points to the same address in memory, a change of one of them will also cause a change of the others.

This should work:

let data = [...Array(3)].map(() => ({ test_1: 0, test_2: true }));

function f(index) {
    data[index].test_1 = 5;
    console.log(data);
}

f(0);
Dor Ben Itzhak
  • 285
  • 2
  • 5