Array(2) gives you an empty array with a length of 2. JavaScript arrays are inherently sparse (they can have holes in them, because they aren't really arrays at all¹), and that's what Array(2) gives you. It looks like this:
+−−−−−−−−−−−−−−+
|    (array)   |
+−−−−−−−−−−−−−−+
| length: 2    |
+−−−−−−−−−−−−−−+
whereas your [undefined, undefined] array looks like this:
+−−−−−−−−−−−−−−+
|    (array)   |
+−−−−−−−−−−−−−−+
| length: 2    |
| 0: undefined |
| 1: undefined |
+−−−−−−−−−−−−−−+
map, forEach, and most (but not all) of the related methods on Array.prototype only loop through the actual entries of a sparse array. Since the array returned by Array(2) doesn't have any actual entries, your callback is never being called.
ES2015 added Array#fill (and it can be shimmed), which you can use to fill an array:
const rand = Array(2).fill().map(Math.random)
console.log(rand);
 
 
(Note that as Me.Name pointed out we don't need item => Math.random,  we can call Math.random directly; it doesn't use this or its arguments (spec).)
There's also this trick for creating a filled array with undefineds in it:
const empty = [...Array(2)]:
...which you could apply like this if you didn't want fill:
const rand = [...Array(2)].map(Math.random);
console.log(rand);
 
 
Ori Drori points out that we can do
Array.from({length: 2}, Math.random);
e.g.:
const rand = Array.from({length: 2}, Math.random);
console.log(rand);
 
 
And Nina Scholz  adds the classic, ES5-compatible:
Array.apply(null, {length: 2}).map(Math.random);
var rand = Array.apply(null, {length: 2}).map(Math.random);
console.log(rand);
 
 
¹ (That's a post on my anemic little blog)