我想创建一个0到1之间的随机数组,所以我尝试了:
var randList = _.map(new Array(5), Math.random);
但是我没有得到我期望的随机元素列表,而是得到了:
console.log(JSON.stringify(randList));
"[null,null,null,null,null]"
为什么我得到一个null数组而不是随机数?
答案 0 :(得分:5)
实际上,你获得了一个undefined
的数组 - 传递给map
的函数甚至没有被触发过一次。这是因为使用new Array(Number)
构造函数创建的数组有点奇怪 - 即使它的长度设置正确,它实际上也没有0
,1
等属性:< / p>
var arr = Array(5);
console.log(arr.length); // 5
console.log('0' in arr); // false
这就是为什么,即使普通的旧版for (var i = 0; i < arr.length; i++)
可以迭代这个数组,for (var i in arr)
也无法工作:
for (var i in arr) {
console.log(i); // won't be called even once!
}
我想,这与Array.map(映射_.map)的情况相似:
var newarr = arr.map(function(el) {
console.log(el); // nope, still nothing
});
console.log(newarr); // [undefined x 5]
那么创建这样一个数组的正确方法是什么?这是:
var rightArr = Array.apply(0, Array(5)); // ah, the pure magic of apply!
// and here goes an array of randoms:
var randArr = rightArr.map(Math.random);
...但当然使用_.times
是这种情况下的方法。 )
答案 1 :(得分:2)
Array(length)
构造函数创建一个稀疏数组。也就是说,数组的长度设置为指定的参数,但不填充数组的元素。因此,map
方法不会迭代这些“未填充的”元素。例如,以下代码段不会在控制台上生成任何输出:
var arr = new Array(5);
for(var x in arr) console.log(x);
但请注意,像这样初始化数组会产生预期的结果:
console.log(_.map([0,0,0,0,0], Math.random));
当然,这不会扩展。如果您希望数组中的元素数量可变,我建议您使用times
方法:
var randList = _(5).times(Math.random);
或
var randList = _.times(5, Math.random);
答案 2 :(得分:0)
只想在raina77ow的优秀答案中添加一些测试用例。
实际上,new Array(5)不会在Array对象中分配5个属性。
无论你使用下划线还是普通的javascript Array.prototype.map(当然是在体面的浏览器中)都没关系。
以下是node.js中的测试用例
new Array(2)只返回一个空对象(无键)和2(假的)占位符
> var a = new Array(2);
> a;
[ , ]
> a.length;
2
> Object.keys(a);
[]
地图结果也是一个带有2个占位符的空对象(无键)
> var result = a.map(Math.random);
> result;
[ , ]
> result.length;
2
> Object.keys(result);
[]
为什么结果是长度为2的数组对象,即使没有做任何事情?
阅读Array.prototype.map polyfill implmentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
地图结果创建为var res = new Array(source_array_length);
此外,即使值为undefined
> [undefined, undefined].map(Math.random);
[ 0.6572469582315534, 0.6343784828204662 ]
好的,我们还测试稀疏数组,长度为2但它只包含一个键'1'。
> var a = []; a[1] = 'somthing';
> a;
[ , 'somthing' ]
> a.length
2
> Object.keys(a);
[ '1' ]
地图结果返回一个长度为2的数组,但只有一个键'1',只触发一个Math.random!
> var result = a.map(Math.random);
undefined
> result.length
2
> result
[ , 0.8090629687067121 ] // only one Math.random fired.
> Object.keys(result);
[ '1' ]