Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: how is 'new Array(4)' different from Array.apply(null, {length: 4})?

I want to generate an empty array of a given length and the populate it with some numbers. One way to generate an array with four sequential numerical elements is :

var x = Array.apply(null, {length: 4}).map(function(item, index){return index;})

But when I saw Array.apply(null, {length: 4}) I thought I could instead replace it with new Array(4) but that is not the case. Doing a quick test yields the following:

>> console.log((new Array(4)))
<< [ <4 empty items> ]

>> console.log(Array.apply(null, {length: 4}))
<< [ undefined, undefined, undefined, undefined ]

Which means I can .map the latter but not the former.

What is the difference then between new Array and Array.apply(null, {}) which I thought were both creating an array object with given length?

like image 870
MikeB Avatar asked Sep 06 '25 08:09

MikeB


1 Answers

apply takes a context as the first parameter and an arraylike list of arguments as a second. Then it calls the function (Array) with the iterable as arguments.

Array.apply(null, [1, 2])
// Same as
Array(1, 2)
// Or
[1, 2]

Now if you pass an object as an arraylike, it will still iterate it like this:

function apply(context, args) {
  for(var i = 0; i < args.length; i++) { 
    /*...*/ args[i];
  }
}

So if you pass { length: 4 } it will iterate four times and take undefined as an argument, so it results in something like:

Array.apply(null, { length: 4 })
// Same as
Array(undefined, undefined, undefined)

Therefore the arrays slots are not empty, but they are undefined, and as map only skips empty slots it will go over every entry of the second array.

By the way, the same can be achieved a bit more readable:

Array.from({length: 4 }, (_, i) => i)
// [0, 1, 2, 3]
like image 137
Jonas Wilms Avatar answered Sep 09 '25 03:09

Jonas Wilms