6

consider I declare two variables like this (done within REPL, with node v7.7.2), which I expect to be arrays:

var x = Array(4)
var y = Array.from({length: 4})

then the following should work identically, but it doesn't:

x.map(Math.random)
[ , , ,  ]
y.map(Math.random)
[ 0.46597917021676816,
  0.3348459056304458,
  0.2913995519428412,
  0.8683430009997699 ]

in looking, it seems x and y are both identical:

> typeof x
'object'
> typeof y
'object'
> Array.isArray(x)
true
> Array.isArray(y)
true
> x.length
4
> y.length
4
> typeof x[0]
'undefined'
> typeof y[0]
'undefined'

so why the difference?

ekkis
  • 9,804
  • 13
  • 55
  • 105

3 Answers3

4

Actually, it should not have the same results fot both cases. See the manual here about Array:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

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 its length property set to that number (Note: this implies an array of arrayLength empty slots, not slots with actual undefined values). If the argument is any other number, a RangeError exception is thrown.

And here about the Array.from() method

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from

Check the following example on the page linked above:

// Generate a sequence of numbers
// Since the array is initialized with `undefined` on each position,
// the value of `v` below will be `undefined`
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]
Diego ZoracKy
  • 2,227
  • 15
  • 14
  • so there's a difference between an "empty" slot and a slot that contains *undefined*? the last stanza in my code indicates that `typeof x[0] == typeof y[0]` is true. so how can I get the difference? – ekkis Mar 30 '17 at 23:45
2

For the first three outputs, Array#map works.

It is not called for missing elements of the array (that is, indexes that have never been set, which have been deleted or which have never been assigned a value).

The ECMA 262 standard to Array.from describes a construction with length for a new array (point 7 ff).

var x = Array(4),
    y = Array.from({ length: 4 }),
    arrayX = x.map(Math.random),
    arrayY = y.map(Math.random),
    z = Array.from({ length: 4 }, Math.random);

console.log(x);
console.log(y);
console.log(arrayX);
console.log(arrayY);
console.log(z);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

The Array created with Array(4) is not iterated over with .map(), whereas the Array.from({ length: 4 }) is iterated over. A fuller explanation can be found at JavaScript "new Array(n)" and "Array.prototype.map" weirdness, you can test this with..

x.map((f,i) => console.log(i)) vs. y.map((f,i) => console.log(i))
Community
  • 1
  • 1
user3094755
  • 1,561
  • 16
  • 20