Photo by Luke Palmer on Unsplash
Occasionally in JavaScript it?s necessary to populate an array with some defaults ? an object, string or numbers. What?s the best approach for the job?
Lately, I?ve been working with Oleksii Trekhleb on a new book based on his Github repo: JavaScript Algorithms and Data Structures. As I?ve worked on writing some chapters and editing the book I came across some gotchas in working with arrays in JavaScript. There are a few different options for creating an array and filling it with default values in JavaScript, and this blog post explains the pros and cons of each option.
Array.fill
Using the Array.fill method is an obvious choice ? you supply the method with the value you want to populate your array with, and the method returns a modified version of the array.
For example, if we want to set up an array with ten slots and populate it with the string ?hello? we?d write some code like this:
let filledArray = new Array(10).fill(‘hello’);
This method works great for immutable values like numbers, strings, and booleans. What if we wanted to populate an array with objects though?
let filledArray = new Array(10).fill({‘hello’:’goodbye’});
This also populates the array with objects, but they all refer to the same object. In the MDN web docs on the fill method it says:
When fill gets passed an object, it will copy the reference and fill the array with references to that object.
So if we change that object like this:
filledArray[0].hello = “adios”
It will change every object in the array because they are all referencing the same object. If we want to populate an array with unique objects, we?d need to use a different approach:
let filledArray = new Array(10).fill(null).map(()=> ({‘hello’:’goodbye’}))
In this approach, we are creating an array with ten empty slots, then filling those slots with the null value, then creating a new array with unique objects. Now when we change an object in the array, we are only changing a specific object, not a reference to an object.
Using the map method is rather expensive though because the map method returns a completely new array, instead of using the existing array. For large datasets, this could get rather expensive. There are some other alternatives to populating an array with objects.
Using a for loop
Rather than using the fill and map methods, we could create a new array like this:
let filledArray = new Array(10);
Then loop over the array the old fashioned way like this:
for(let i=0; i<bucket_size;i++){ filledArray[i] = {‘hello’:’goodbye’};}
This avoids using the map method.
Using Array.from
Another alternative is to use the Array.from method. From the MDN docs:
Array.from() lets you create Arrays from:
array-like objects (objects with a length property and indexed elements) oriterable objects (objects where you can get its elements, such as Map and Set).
let filledArray = Array.from({length:10},()=> ({‘hello’:’goodbye’}))
In this one-liner, the first argument of the from method is the object we want to create an array from. In this case, we are creating an empty object with a length property set to 10. The second argument is a function that fills the array with whatever the result of our function is ? in our case it is our hello object.
Using spread syntax
Our final option is to use the array spread syntax:
let filledArray = […new Array(10)].map(()=> {‘hello’:’goodbye’});
The array spread syntax allows you to expand an array or string and create a new array from the expanded elements. By using the array spread syntax, we avoid the need to use the fill method but we?re still using the map method which can get expensive.
I?m excited about the launch of this book in early March. Sign up below if you want to get more updates on book progress and get some good discounts when it launches!
Thanks to Devin Abbott and Nate Murray for help with writing this blog post.