Stormsyders
Stormsyders

Reputation: 285

Javascript nested array single element modification transforms into whole array modification

I am having issues with this code:

var openingSegments = Array(7).fill([]);
openingSegments[0].push({'start': '1100', 'end': '1900'});

Because when I do:

console.log(openingSegments);

It gives me :

[ [ { start: '1100', end: '1900' } ],
  [ { start: '1100', end: '1900' } ],
  [ { start: '1100', end: '1900' } ],
  [ { start: '1100', end: '1900' } ],
  [ { start: '1100', end: '1900' } ],
  [ { start: '1100', end: '1900' } ],
  [ { start: '1100', end: '1900' } ] ]

As if I had pushed all the elements of 'hoursOfDay' which is not the case since i only applied push on the very first element (index 0).

What is happening here ?

Upvotes: 0

Views: 37

Answers (2)

Kristian Sakarisson
Kristian Sakarisson

Reputation: 31

Array.fill just fills your array with the exact same objects.

This is basically how fill works:

function fillFunc(size, element) {
  const resultArray = [];
  for (let i = 0; i < size; ++i) {
    resultArray.push(element);
  }
  return resultArray;
}
const filledArray = fillFunc(7, []);

As you can see, the resulting array just gets filled with references to the initial object. I'd go with something other than Array.fill() for your particular needs.

Upvotes: 0

Suren Srapyan
Suren Srapyan

Reputation: 68665

fill just copies the passed argument across all items. Actually you have only one array object and 7 reference copies of that object pushed into the array. Changing array via one reference affects all items.

Instead of fill you can use Array#from function with the mapFn parameter of it.

var openingSegments = Array.from({ length: 7 }, x => []);
openingSegments[0].push({'start': '1100', 'end': '1900'});

console.log(openingSegments[0]);
console.log(openingSegments[1]);

Upvotes: 3

Related Questions