Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does `new Array(5).map()` work? [duplicate]

I've recently discovered that mapping an uninitialised array doesn't seem to work as I would expect. With this code:

function helloMap(value, index) {
    return "Hello " + index;
}

console.clear();

var initialArray = Array.apply(null, new Array(5));

console.log("Array initialised with apply:");
console.log(initialArray);
console.log(initialArray.map(helloMap));

var normalArray = new Array(5);

console.log("Array constructed normally");
console.log(normalArray);
console.log(normalArray.map(helloMap));
.as-console-wrapper {
  max-height: 100% !important;
}

I get different results despite the first output for each array being [undefined, undefined, undefined, undefined, undefined].

The fact that I get different results implies that the undefined in these 2 arrays are in fact different. In the first I suspect that the array has 5 items in, each one is undefined. In the second the array is 5 items long but there is nothing, not even undefined in there...

It's a bit confusing.

Can someone explain it to me?

like image 789
Roaders Avatar asked Apr 06 '17 13:04

Roaders


2 Answers

Array.apply(null, Array(5)) actually fills the array (or array-like object) that you pass as the second argument with the value of the first argument you pass in, as can be seen in the MDN Docs.

new Array(5) is just initializing an array with it's length property set to the argument of 5. Again, as can be seen in the MDN docs:

If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with its length property set to that number (Note: this implies an array of arrayLength empty slots, not slots with actual undefined values).

like image 83
jeffdill2 Avatar answered Sep 21 '22 00:09

jeffdill2


According to MDN Array.prototype.map

map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values, including undefined. It is not called for missing elements of the array (that is, indexes that have never been set, which have been deleted or which have never been assigned a value).

Both the arrays are different in the way Array.map executes the callback. Since the array in second scenario doesn't have indexes map is returning empty

REASON

The answer lies in Array constructor

In the first scenario you are passing an array with length 5 to Array constructor which will index the array based on the length but in the second scenario you are just using the array with length 5

You will get to know the difference when you run Object.keys(initialArray) with Object.keys(normalArray)

Try checking the below example.

function helloMap(value, index) {
    return "Hello " + index;
}

console.clear();

var initialArray = Array.apply(null, new Array(5));

console.log("Array initialised with apply:");
console.log(initialArray);
console.log(initialArray.map(helloMap));

var normalArray = new Array(5);

console.log("Array constructed normally");
console.log(normalArray);
console.log(normalArray.map(helloMap));

//DIFFERENCE
console.log("Initial Array: "+Object.keys(initialArray));
console.log("Normal Array: "+Object.keys(normalArray));
.as-console-wrapper {
  max-height: 100% !important;
}
like image 33
Gangadhar JANNU Avatar answered Sep 19 '22 00:09

Gangadhar JANNU