[undefined, undefined, undefined].map(function(val, i) { return i });
returns [0, 1, 2], while
Array(3).map(function(val, i) { return i });
returns [undefined, undefined, undefined].
Why?
[undefined, undefined, undefined].map(function(val, i) { return i });
returns [0, 1, 2], while
Array(3).map(function(val, i) { return i });
returns [undefined, undefined, undefined].
Why?
Share Improve this question asked Feb 13, 2013 at 14:24 accmeaccme 3831 gold badge2 silver badges11 bronze badges 05 Answers
Reset to default 13In the first case you've defined and initialized a new array with three undefined
values, whereas in the second case you've only defined an array with possible length of 3.
new Array(3)
is the same as you do:
var arr = [];
arr.length = 3;
As a result, having .length
property implicitly defined, .map()
method can do the iteration over the array allocated in memory, which basically holds zero defined items (i.e. purely empty).
You are declaring pointers to undefined objects writing undefined
. Thus, [undefined]
creates an array of a pointer to undefined. new Array(3)
creates an array of undefined pointers, which are not looped over by array prototype methods (including .map
).
MDN Reference. The variable undefined
is actually assigning a value even though it points to undefined
.
Array(3)
just takes an empty array and manually assigns it a length:
> a = []
[]
> a.length = 3
3
> a
[ , , ]
Which is not the same thing as manually constructing an array containing undefined elements:
> a = [undefined, undefined, undefined]
[ undefined, undefined, undefined ]
The MDN documentation for Array explains exactly what is going on:
If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), a new, empty JavaScript array and its length is set to that number. If the argument is any other number, a RangeError exception is thrown.
So the array is initialized to an empty array []
. This explains why map
does not process any of the array elements, because there are none.
A few examples may help. When the array is initialized using Array(3)
it is empty so map
has nothing to iterate over:
> Array(3)
.map(function(val, i) { console.log(i); return i; });
[ , , ]
Compare that with the following example, where you can see that each intermediate array value is output to the console:
> [undefined, undefined, undefined]
.map(function(val, i) { console.log(i); return i; });
0
1
2
[ 0, 1, 2 ]
As @VisioN mentioned, Array(3) is defined but uninitialized. Interestingly, you can pass the uninitialized array through Array.apply, and initialize it. I've used this to fill arrays:
Array.apply(null, Array(3)).map(function(val,i) { return i; });
// [0, 1, 2]
<script type="text/javascript">
test();
test2();
function test() {
[undefined, undefined, undefined].map(function(val, i) { console.log("un: " + val + "/" + i); return i; });
}
function test2() {
Array(3).map(function(val, i) { console.log("no: " + val + "/" + i); return i; });
}
</script>
test() function returns:
un: undefined/0 un: undefined/1 un: undefined/2
test2() function does not return a value;
- test() you have an object with that contains 3 values (undefined)
- test2() has an empty array of length 3