Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused by behavior of `map` on arrays created using `new` [duplicate]

I am confused by the results of mapping over an array created with new:

function returnsFourteen() {
    return 14;
}

var a = new Array(4);
> [undefined x 4] in Chrome, [, , , ,] in Firefox
a.map(returnsFourteen);
> [undefined x 4] in Chrome, [, , , ,] in Firefox

var b = [undefined, undefined, undefined, undefined];
> [undefined, undefined, undefined, undefined]
b.map(returnsFourteen);
> [14, 14, 14, 14]

I expected a.map(returnsFourteen) to return [14, 14, 14, 14] (the same as b.map(returnsFourteen), because according to the MDN page on arrays:

If the only argument passed to the Array constructor is an integer between 0 and 2**32-1 (inclusive), a new JavaScript array is created with that number of elements.

I interpret that to mean that a should have 4 elements.

What am I missing here?

like image 226
Matt Fenwick Avatar asked Jul 27 '12 15:07

Matt Fenwick


People also ask

Does map create a new array?

map() creates a new array from calling a function for every array element. map() calls a function once for each element in an array. map() does not execute the function for empty elements. map() does not change the original array.

Does JS map modify original array?

Array Iterator Array. map() creates the new array with the same number of elements or does not change the original array.

Can you map two arrays?

To map multiple arrays with JavaScript, we can use the map method. to define the zip function that calls a1. map to combine the entries from a1 and a2 with index i into one entry. Then we call zip with arr1 and arr2 to zip them into one array.

Does array map preserve order?

The underlying issue isn't because of map , which should preserve the order. Rather, user.jobs itself may be in a different order (in each test) since there isn't any explicit order by clause used. Without an explicit order by , you can't guarantee the order of the jobs even if you create them in a specific order.


2 Answers

When you create an array like so:

var arr1 = new Array( 4 );

you get an array that has a length of 4, but that has no elements. That's why map doesn't tranform the array - the array has no elements to be transformed.

On the other hand, if you do:

var arr2 = [ undefined, undefined, undefined, undefined ];

you get and array that also has a length of 4, but that does have 4 elements.

Notice the difference between having no elements, and having elements which values are undefined. Unfortunately, the property accessor expression will evaluate to the undefined value in both cases, so:

arr1[0] // undefined
arr2[0] // undefined

However, there is a way to differentiate these two arrays:

'0' in arr1 // false
'0' in arr2 // true
like image 58
Šime Vidas Avatar answered Oct 23 '22 23:10

Šime Vidas


var a = new Array(4);

This defines a new array object with an explicit length of 4, but no elements.

var b = [undefined, undefined, undefined, undefined];

This defines a new array object with an implicit length of 4, with 4 elements, each with the value undefined.

From the docs:

callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.

For array a, there are no elements that have been assigned values, so it does nothing.

For array b, there are four elements that have been assigned values (yes, undefined is a value), so it maps all four elements to the number 14.

like image 45
jbabey Avatar answered Oct 23 '22 23:10

jbabey