看一些javascript代码,我看到了(像这样):
var arr = Array.apply(null, {length: 10});
阅读Function.prototype.apply()的MDN文档,我了解到虽然它通常期望一个数组作为其第二个参数,它是要传递给被调用函数的参数数组,
你也可以使用类似于数组的任何类型的对象,所以在实践中这意味着它将具有属性长度和范围内的整数属性(0 ...长度)。
所以从我所知道的,它调用Array()好像它传递了10个参数,但由于它没有定义任何这些“整数属性”,所以就好像传递了10个未定义的参数一样。 这是正确的吗?
console.log(arr);
产量
[未定义, 不确定的, 不确定的, 不确定的, 不确定的, 不确定的, 不确定的, 不确定的, 不确定的, undefined]
与
的结果完全不同var barr = new Array(10);
console.log(barr);
是
[,,,,,,,,,,
这些数组的行为也不同。
console.log(arr.map(function(item) { return 'hi';}));
console.log(barr.map(function(item) { return 'hi';}));
给出
['hi','hi','hi','hi','hi','hi','hi','hi','hi','hi']
[,,,,,,,,,,
我想知道为什么地图功能不适用于第二个。所以我检查了console.log(1 in arr);
,它给了 true 和`console.log(1 in barr);'这给了 false 。
所以我目前的猜测是arr是一个包含10个变量的数组,每个变量的值都是 undefined ,而barr是一个数组,尽管它的长度为10,但是没有整数属性。并且Array.apply有效,因为它询问{length:10}它的属性 0 是什么,接收 undefined ,因此将 undefined 分配给属性它正在构建的数组的 0 ,依此类推。我的推理是否正确?是否真的没有那么简单的方法来定义一个数组,该数组包含其范围内每个索引的未定义整数属性,而不是根本没有整数属性?因为看着这个,我觉得new Array()
很没用。
答案 0 :(得分:5)
从我所知道的,它调用Array()就像传递了10个参数一样,但由于它没有定义任何"整数属性",它&& #39; s好像它传递了10个未定义的参数。这是对的吗?
是的,确切地说。它这样做:
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
var barr = new Array(10); console.log(barr);
...
console.log(arr.map(function(item) { return 'hi';})); console.log(barr.map(function(item) { return 'hi';}));
我想知道为什么地图功能对第二个功能不起作用。
由于map
,forEach
和类似内容仅访问实际存在的属性。正如你所说,它们之间存在很大的差异。
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
// Or `var arr = Array.apply(null, {length: 10});
和
var barr = new Array(10);
在第一个示例中,arr
有10个条目,每个条目的值都为undefined
。在第二个示例中,barr
包含没有条目和length
10
。因此,在第一个中,map
将访问属性,因为它们存在。在第二个中,它不会,因为他们不会。
回想一下JavaScript中的标准数组aren't really arrays at all (披露:我博客上的帖子),他们反对某些特殊行为的对象。因此,它们本质上是稀疏的:
var a = [];
a.length = 10000;
a
没有10,000个条目。它有没有条目。它的length
属性为10000
。
您可以使用hasOwnProperty
或in
来判断该媒体资源是否存在。比较:
var barr = new Array(10);
console.log(barr.hasOwnProperty(0)); // false
console.log(0 in barr); // false
为:
var arr = Array.apply(null, {length: 10});
console.log(arr.hasOwnProperty(0)); // true
console.log(0 in arr); // true
并且
Array.apply
有效,因为它询问{length: 10}
其属性0
是什么,接收undefined
,因此将undefined
分配给属性0
它构建的数组,等等。我的推理是否正确?
是的,虽然要明确,apply
询问属性0
是什么,然后在调用时将其作为第一个参数Array
。它的Array
然后获取第一个参数的值并将其分配给它正在创建的数组上的0
属性。
对于定义一个包含其范围内每个索引的未定义整数属性的数组,而不是根本没有整数属性,是否真的没有简单的hackish方式?
仅轻微:ES2015添加Array.from
,它接受类似数组的对象并返回一个真实数组(可选择映射条目)。那就是:
var arr = Array.from({length:10});
与简单a = new Array(bigNumberHere);
或a = []; a.length = bigNumberHere
相反,这种情况很少见。例如,如果财产不存在或存在价值undefined
,您很多时候都不在乎。有时你这样做,但是为了给你提供观点,我已经专业地编写了20年的JavaScript,在过去的8年里,我已经非常注重了,而且我可能很关心,哦,一次或两次,顶部。
您提到在您处理的具体案例中,它与map
合并,因此Array.from
将取代两者:
var arr = Array.from({length: 10}, function() { return "hi"; });
...产量
["hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi"]
尽管Array.from
是ES2015中的新功能,但它可以在较旧的JavaScript引擎上进行填充/填充。
答案 1 :(得分:1)
这是对的吗?
是
你也可以使用任何类似于数组的对象,所以 实践这意味着它将具有属性长度和整数 范围内的属性(0 ...长度)。
它表示您可以传递数组的 duck-type :具有某种接口的对象:
这将被视为一个数组。 所以传递一个{length:10}就像传递一个真正的数组[undefined,undefined,undefined,..] 创建每个索引并且值未定义的地方。
所以第一个代码行:
var arr = Array.apply(null, {length: 10});
被解释为:
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
所以我目前的猜测是arr是一个包含整数的数组 属性10个变量,每个变量的值都是undefined和 barr是一个数组,虽然长度为10,但没有整数 属性。
是
var test = Array(10);
输出:[undefined x10]< - 没有索引,只有一个简单的属性'长度'与真实内容不一致,但对于检索它并做一些大小的考虑是有用的。
test[2] = undefined;
输出:[undefined x2,undefined,undefined x7]< - 没有索引,除了位置' 2'有一个值:undefined。