I've observed this in Firefox-3.5.7/Firebug-1.5.3 and Firefox-3.6.16/Firebug-1.6.2
When I fire up Firebug:
>>> x = new Array(3)
[undefined, undefined, undefined]
>>> y = [undefined, undefined, undefined]
[undefined, undefined, undefined]
>>> x.constructor == y.constructor
true
>>> x.map(function(){ return 0; })
[undefined, undefined, undefined]
>>> y.map(function(){ return 0; })
[0, 0, 0]
What's going on here? Is this a bug, or am I misunderstanding how to use new Array(3)
?
With ES6, you can do
[...Array(10)].map((a, b) => a)
, quick and easy!Not a bug. That's how the Array constructor is defined to work.
From MDC:
The
.map()
method only includes in the iteration elements of the array that have explicitly had values assigned. Even an explicit assignment ofundefined
will cause a value to be considered eligible for inclusion in the iteration. That seems odd, but it's essentially the difference between an explicitundefined
property on an object and a missing property:The object
x
does not have a property called "z", and the objecty
does. However, in both cases it appears that the "value" of the property isundefined
. In an array, the situation is similar: the value oflength
does implicitly perform a value assignment to all the elements from zero throughlength - 1
. The.map()
function therefore won't do anything (won't call the callback) when called on an array newly constructed with the Array constructor and a numeric argument.I had a task that I only knew the length of the array and needed to transform the items. I wanted to do something like this:
To quickly create an array like this:
But it didn't worked because: see Jonathan Lonowski's answer a few answers upper.
Solution could be to fill up the array items with any value (even with undefined) using Array.prototype.fill()
Update
Another solution could be:
Just ran into this. It sure would be convenient to be able to use
Array(n).map
.Array(3)
yields roughly{length: 3}
[undefined, undefined, undefined]
creates the numbered properties:{0: undefined, 1: undefined, 2: undefined, length: 3}
.The map() implementation only acts on defined properties.
If you are doing this in order to easily fill up an array with values, can't use fill for browser support reasons and really don't want to do a for-loop, you can also do
x = new Array(3).join(".").split(".").map(...
which will give you an array of empty strings.Quite ugly I have to say, but at least the problem and intention are quite clearly communicated.
The arrays are different. The difference is that
new Array(3)
creates an array with a length of three but no properties, while[undefined, undefined, undefined]
creates an array with a length of three and three properties called "0", "1" and "2", each with a value ofundefined
. You can see the difference using thein
operator:This stems from the slightly confusing fact that if you try to get the value of a non-existent property of any native object in JavaScript, it returns
undefined
(rather than throwing an error, as happens when you try to refer to a non-existent variable), which is the same as what you get if the property has previously been explictly set toundefined
.