The Hidden Trap of Array.prototype.fill()

๐ TLDR;
If your initialisation involves populating an array with non-primitive types (arrays, objects, sets, etc.), never use fill() as it creates a single instance of the array/object passed to it, and fills values of the array with its reference.
Use Array.from() with a mapping function to guarantee that every element is a unique, independent instance.
For your next interview problem or complex project, remember this ruleโit might save you hours of painful debugging! Happy coding!
When solving the Top K frequent problem using the bucket approach, I needed an array of N+1 unique slots, where N is the maximum possible frequency (nums.length). Each slot must be an independent array.
My initial line of code looked like this:
JavaScript
const maxFrequency = nums.length;
const buckets = new Array(maxFrequency + 1).fill([]);
๐ง What Actually Happens: Shared References
The core issue is that fill() only accepts a single value as an argument. When that value is a non-primitive type (like an array or an object), JavaScript does the following:
It creates one single empty array in memory:
[].It then puts a reference to this single, same array into every single index of the
bucketsarray.
The Crux: When my frequency map told me to place a number with frequency 3 into buckets[3], I wrote:
JavaScript
buckets[3].push(num); // I thought I was only affecting bucket 3...
But because buckets[3], buckets[0], buckets[1], and all the others were all pointing to the exact same array object in memory, every bucket got the number! My entire bucket structure was completely corrupted. This is why my "Top K" solution was not working correctly for all test cases.
โ
The Solution: Array.from({ length }, () => [])
The correct way to initialize an array where every element needs to be a unique instance of an object (like a unique bucket array) is to use the Array.from() method with a mapping function.
JavaScript
const maxFrequency = nums.length;
const buckets = Array.from({ length: maxFrequency + 1 }, () => []);
๐ก Why This Works: The Map Function Creates Unique Instances
Array.from() is designed to create a new array from an iterable or array-like object (like { length: N }). Critically, the second argument is a map function that is executed for every index.
The map function here is () => []. For each of the N+1 positions:
Array.from()executes() => [].The function returns a brand new, unique empty array instance.
| Method | Creates | Resulting References | Impact on Buckets |
fill([]) | One [] | All elements point to the same array. | Modifying one bucket affects all buckets. |
Array.from(..., () => []) | N [] instances | Each element points to a unique array. | Modifying one bucket affects only that one bucket. |
Switching to Array.from() instantly fixed the issue. My buckets were properly isolated, my logic worked, and I finally got that sweet "Accepted" status.

