Rowanto Luo


Just another blog. or log.


JavaScript, beware of filling an array with empty array.

I love JavaScript, however very often, it doesn't love me back.

const dataBuffers = new Array(4);  
dataBuffers.fill([]);

for (let i = 0; i < 4; i += 1) {  
  dataBuffers[i].push(7);
}

console.log(JSON.stringify(dataBuffers));  
// guess what is the answer?

If you guess the answer would be [[7],[7],[7],[7]], then think again.

The problem is that dataBuffers.fill([]) will create you a single array, and fills the dataBuffers with the reference of the array. It is actually pretty clear if you have done JavaScript long enough, but one might be stuck with the impression that the dataBuffers is filled with an empty array. In actuality, they all reference to the single same array, which means, the result of the above is.

const dataBuffers = new Array(4);  
dataBuffers.fill([]);

for (let i = 0; i < 4; i += 1) {  
  dataBuffers[i].push(7);
}

console.log(JSON.stringify(dataBuffers));  
// [[7,7,7,7],[7,7,7,7],[7,7,7,7],[7,7,7,7]]

So if you want to fill an array with an empty array, there is no other way than to do it manually:

const dataBuffers = new Array(4);  
for (let i = 0; i < 4; i += 1) {  
  dataBuffers[i] = [];
}

for (let i = 0; i < 4; i += 1) {  
  dataBuffers[i].push(7);
}

console.log(JSON.stringify(dataBuffers));  
// [[7],[7],[7],[7]]

We might be able to do elegantly, by introducing a new fill method which takes in a function, and apply the result of the function as the filling.

const lazyFill = (array, supplier) => {  
  for (let i = 0; i < array.length; i += 1) {
    array[i] = supplier();
  }
};

const dataBuffers = new Array(4);  
lazyFill(dataBuffers, () => []);

for (let i = 0; i < 4; i += 1) {  
  dataBuffers[i].push(7);
}

console.log(JSON.stringify(dataBuffers));  
// [[7],[7],[7],[7]]

My stupidity in this cost me a day of development time, and for me I am not able to debug it to find the problem since it is an application for my raspberry pi, and it can only run there because of the custom device attached to it. Hopefully this will help anyone stumbling upon the same problem.