DEV Community 👩‍💻👨‍💻

Cover image for The tricks of Javascript
Bruno Noriller
Bruno Noriller

Posted on • Originally published at linkedin.com

The tricks of Javascript

Here’s a trick question:

const arr = Array(5).fill([]);
const arr2 = arr.map((subArr, i) => subArr.push(i));
Enter fullscreen mode Exit fullscreen mode

What is the final value of arr? And the final value of arr2?

This might be something you see people asking in an interview... and before you go console.log({ arr, arr2 }), it’s important to know the why more than the answer.

An array is a value that will always be passed “as reference”, which means it’s pointing somewhere in memory and it simply uses that.

In contrast, a value like a string or a number is passed “by value”, meaning it’s copied to where it’s needed.

And as weird as it might seem when you say it to fill with [] you’re telling Javascript to use the same reference in all instances.

So, when you map, you’re pushing the index to the same reference, over and over.


What about the second one then?

Well... that’s even more trick! Because that’s just what push returns!

And if you didn’t know... push returns the length of the array after the push.

And since it’s inside a map, that returns a new array... it’s easy to understand what’s going on.


The result

And so it prints this:

{
  arr: [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]],
  arr2: [1, 2, 3, 4, 5]
}
Enter fullscreen mode Exit fullscreen mode

And not gonna lie...

This didn’t come from an interview or anything like it... but from a test I was doing that as you might have imagined, wasn’t doing what I wanted it to do.


The “fix”:

const arr = Array(5).fill().map(() => []);
const arr2 = arr.map((subArr, i) => subArr.push(i));

console.log({ arr, arr2 });
/*
  {
    arr: [ [ 0 ], [ 1 ], [ 2 ], [ 3 ], [ 4 ] ],
    arr2: [ 1, 1, 1, 1, 1 ]
  }
*/
Enter fullscreen mode Exit fullscreen mode

Just Array(5).map(() => []) doesn’t work, since Array(n) creates an array of “empty slots” that you can access directly, but you can’t do much else, so you need the fill() to replace those “voids” with undefined.


Why does this work?

This one works because map iterates over the array and each of the [] is actually a new object that is passed by reference since each iteration uses a new scope.

If you were to initialize a [] outside and pass it... then we would be back to square one.


Cover Photo by Natalia Y on Unsplash

Top comments (0)

Let's Get Hacking

Join the DEV x Linode Hackathon 2022 and use your ingenuity and creativity to build using Linode.

Join the Hackathon <-