14
[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?

accme
  • 383
  • 1
  • 2
  • 11

5 Answers5

13

In 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).

VisioN
  • 143,310
  • 32
  • 282
  • 281
4

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.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • So you mean Array(1)[0] is a differrent value internally than [undefined][0]? – Matt Zeunert Feb 13 '13 at 14:33
  • @Matt no, I believe that they dereference the same. – Explosion Pills Feb 13 '13 at 14:35
  • 1
    Its not a different value. The second one has a reference to the value `undefined` because the global Objects `undefined` property is initially set to the value `undefined` therefore referencing to `undefined` wheras `Array(1)` has an undefined reference. Which evaluates to the same value `undefined` so `Array(1)[0] === [undefined][0] //true` like `var undefined2;new Array(1)[0] === [undefined2][0]` where `undefined2` contains a reference to the value `undefined` – Moritz Roessler Feb 13 '13 at 14:37
1

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 ]
Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
1

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]
Community
  • 1
  • 1
zertosh
  • 5,333
  • 1
  • 17
  • 9
0
<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
Darren
  • 68,902
  • 24
  • 138
  • 144