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)
?
Here's a simple utility method as a workaround:
Simple mapFor
Complete Example
Here's a more complete example (with sanity checks) which also allows specifying an optional starting index:
Counting Down
Manipulating the index passed to the callback allows counting backwards:
ES6 solution:
Doesn't work on typescript (2.3), though
In ECMAScript 6th edition specification.
new Array(3)
only define propertylength
and do not define index properties like{length: 3}
. see https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array-len Step 9.[undefined, undefined, undefined]
will define index properties and length property like{0: undefined, 1: undefined, 2: undefined, length: 3}
. see https://www.ecma-international.org/ecma-262/6.0/index.html#sec-runtime-semantics-arrayaccumulationElementList
Step 5.methods
map
,every
,some
,forEach
,slice
,reduce
,reduceRight
,filter
of Array will check the index property byHasProperty
internal method, sonew Array(3).map(v => 1)
will not invoke the callback.for more detail, see https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array.prototype.map
How to fix?
It appears that the first example
Creates an array with undefined pointers.
And the second creates an array with pointers to 3 undefined objects, in this case the pointers them self are NOT undefined, only the objects they point to.
As map is run in the context of the objects in the array I believe the first map fails to run the function at all while the second manages to run.
From the MDC page for
map
:[undefined]
actually applies the setter on the index(es) so thatmap
will iterate, whereasnew Array(1)
just initializes the index(es) with a default value ofundefined
somap
skips it.I believe this is the same for all iteration methods.
I think the best way to explain this is to look at the way that Chrome handles it.
So what is actually happening is that new Array() is returning an empty array that has a length of 3, but no values. Therefore, when you run
x.map
on a technically empty array, there is nothing to be set.Firefox just 'fills in' those empty slots with
undefined
even though it has no values.I don't think this is explicitly a bug, just a poor way of representing what is going on. I suppose Chrome's is "more correct" because it shows that there isn't actually anything in the array.