Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manufacturing an array - why is it different? [duplicate]

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?

like image 909
ekkis Avatar asked Mar 29 '17 20:03

ekkis


3 Answers

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]
like image 157
Diego ZoracKy Avatar answered Oct 28 '22 04:10

Diego ZoracKy


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);
like image 37
Nina Scholz Avatar answered Oct 28 '22 04:10

Nina Scholz


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))
like image 39
user3094755 Avatar answered Oct 28 '22 03:10

user3094755