7

I want to create empty array with fixed length, and then use .map on it to return new array. However, it's not working as expected.

According to mdn docs:

If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with length set to that number.

new Array(3) returns [undefined × 3]. Shouldn't it be: [undefined, undefined, undefined]?

Let's consider following examples:

1) Not working.

var a = new Array(3);
a.map((x, i) => i); // [undefined × 3]

2) Working.

var a = Array.apply(null, new Array(3));
a.map((x, i) => i); // [0, 1, 2]

I tested this on latest Google Chrome Canary.

Eggy
  • 4,052
  • 7
  • 23
  • 39
  • Ok, I first thought this was madness but I can confirm Chrome 47.0.2526.106 m outputs `[undefined × 3]` – Jonathan Jan 10 '16 at 13:19
  • 1
    `Array [ <3 empty slots> ]` in Firefox. The more you know. – Johannes Jander Jan 10 '16 at 13:22
  • 2
    `new Array(3)` does not create an array with elements, its only a dummy – CoderPi Jan 10 '16 at 13:23
  • `new Array(3)` creates an empty array (all indices are not defined) where only the `length` property is set to `3`. `Array.apply(null, new Array(3))` is the same as `new Array(undefined, undefined, undefined)` which creates an array of length 3 where each index has the value `undefined` – Andreas Jan 10 '16 at 13:25
  • @CodeiSir `new Array(3)` has different output than setting `length = 3` on an empty array. (But results in having the same properties on closer inspection [fiddle](https://jsfiddle.net/aydszckb/)) – Jonathan Jan 10 '16 at 13:25
  • @CodeiSir Looks like setting `.length` doesn't fill array with undefined. That is so weird. – Eggy Jan 10 '16 at 13:30
  • i'll ad some information later, so you can understand better. just dont have time right now – CoderPi Jan 10 '16 at 13:34

3 Answers3

3

From the MDN: this returns a new JavaScript array with length set to that number

The Array created by new Array(n) does not have any elements, only a length. That's why you can't map the (not existing) elements.

CoderPi
  • 12,985
  • 4
  • 34
  • 62
  • [undefined, undefined, undefined].map(function(x, i) {return i}) returns [0,1,2] - in this case each value is undefined. The array invoked by new Array(3) has no values – CoderPi Jan 10 '16 at 13:48
  • @torazaburo not realy `new Array(3)[0]` returns `undefined`, because the Element has no value, but internaly it does not have the value `undefined`, it just does not exist.. So in some cases it will look like it has values equal to undefined, but it does not have any elements – CoderPi Jan 10 '16 at 13:50
  • @torazaburo well how could it skip non existing elements if they are not exsisting. But I get you, good addition if someone gets the point^^ – CoderPi Jan 10 '16 at 13:51
1

map skips over undefined elements, by design.

From the documentation:

callback is invoked only for indexes of the array which have assigned values

There are many questions here on SO related to this topic, and providing ways to create arrays that map will operate on all elements of, such as

new Array(3) . fill() . map(...

to take just one example, using the new Array#fill method.

  • There is a difference between indices that have a value of undefined and undefined indices... – Jonathan Jan 10 '16 at 13:41
  • Yes, good point. `map` skips over the latter, but nor the former, as made clear in the documentation, which says "indexes of the array which have assigned values, including undefined". This is actually why `fill` works. It assigns the value `undefined` to each element. –  Jan 10 '16 at 13:42
  • I don't think your comment on OP is correct, `[undefined × 3]` is not `[undefined, undefined, undefined]`. The first notation seems to indicate the indices are not defined – Jonathan Jan 10 '16 at 13:44
  • You are right: `[null, , undefined].map((x, i) => i); // [0, undefined × 1, 2]`. However I was thinking that Array constructor fill it with `undefined`. Also, there are many way to achive what I am trying to do, `.fill()` might do, but the fastest I "discovered" is `[...Array(3)].map((x, i) => i);` – Eggy Jan 10 '16 at 13:44
  • thats wrong.. `[undefined, undefined, undefined].map(function(x, i) {return i})` returns `[0,1,2]` - in this case each value is `undefined`. The array invoked by `new Array(3)` has no values – CoderPi Jan 10 '16 at 13:46
  • @CodeiSir To whom is the "that's wrong" comment addressed? –  Jan 10 '16 at 13:53
  • to you, you stated that the are the same, but I think you removed the Post. I'll leave the comment as an example – CoderPi Jan 10 '16 at 13:55
0

An example in a addition to CodeiSirs answer:

// foo and bar are identical. They are arrays with length 3 and no indices.
var foo = new Array(3);
var bar = [];
bar.length = 3;

console.log(foo);
console.log(bar);

// This is different. It has 3 indices with the value undefined.
var pez = [undefined, undefined, undefined];
console.log(pez);

The console displays new Array(3) kind of weird because it's not the same as [undefined, undefined, undefined]

Jonathan
  • 8,771
  • 4
  • 41
  • 78