使用JavaScript中的新Array()定义未定义的值

Poo*_*eas 7 javascript arrays properties

看一些javascript代码,我看到(类似)这个:

var arr = Array.apply(null, {length: 10});
Run Code Online (Sandbox Code Playgroud)

阅读Function.prototype.apply()的MDN文档,我了解到虽然它通常期望一个数组作为它的第二个参数,它是要传递给被调用函数的参数数组,

你也可以使用类似于数组的任何类型的对象,所以在实践中这意味着它将具有属性长度和范围内的整数属性(0 ...长度).

所以从我所知道的,它调用Array()好像它传递了10个参数,但由于它没有定义任何这些"整数属性",所以就好像它传递了10个未定义的参数.那是对的吗?

console.log(arr);
Run Code Online (Sandbox Code Playgroud)

产量

[undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined]

这与结果完全不同

var barr = new Array(10);
console.log(barr);
Run Code Online (Sandbox Code Playgroud)

是的

[,,,,,,,,,]

这些阵列的行为也不同.

console.log(arr.map(function(item) { return 'hi';}));
console.log(barr.map(function(item) { return 'hi';}));
Run Code Online (Sandbox Code Playgroud)

['hi','hi','hi','hi','hi','hi','hi','hi','hi','hi']

[,,,,,,,,,]

我想知道为什么map函数不能用于第二个.所以我检查了console.log(1 in arr);哪个给了true和`console.log(1 in barr);' 这给了.

所以我目前的猜测是arr是一个数组,它包含10个变量作为整数属性,每个变量的值都是undefined,而barr是一个数组,尽管它的长度为10,但没有整数属性.并且Array.apply可以工作,因为它询问{length:10}它的属性0是什么,接收未定义,因此将undefined分配给它正在构造的数组的属性0,依此类推.我的推理是否正确?是否真的没有那么简单的方法来定义一个数组,该数组包含其范围内每个索引的未定义整数属性,而不是根本没有整数属性?因为看这个,在我看来这new Array()是无用的.

T.J*_*der 5

所以从我所知道的,它调用Array()好像它传递了10个参数,但由于它没有定义任何这些"整数属性",所以就好像它传递了10个未定义的参数.那是对的吗?

对,就是这样.这样做:

var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
Run Code Online (Sandbox Code Playgroud)
var barr = new Array(10);
console.log(barr);
Run Code Online (Sandbox Code Playgroud)

...

console.log(arr.map(function(item) { return 'hi';}));
console.log(barr.map(function(item) { return 'hi';}));
Run Code Online (Sandbox Code Playgroud)

我想知道为什么map函数不能用于第二个.

因为map,forEach和类似的只访问实际存在的属性.正如你所说,两者之间存在很大差异.

var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
// Or `var arr = Array.apply(null, {length: 10});
Run Code Online (Sandbox Code Playgroud)

var barr = new Array(10);
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,arr有10个条目,每个条目都有值undefined.在第二示例中,barr具有没有项length10.所以在第一个,map将访问属性,因为它们存在.在第二个,它不会,因为他们没有.

回想一下,JavaScript 中的 标准数组根本就不是数组(披露:这是我博客上的帖子),它们是具有某些特殊行为的对象.因此,它们天生就是稀疏的:

var a = [];
a.length = 10000;
Run Code Online (Sandbox Code Playgroud)

a没有10,000个条目.它没有条目.这只是它的length财产10000.

您可以使用hasOwnProperty或来判断属性是否存在in.相比:

var barr = new Array(10);
console.log(barr.hasOwnProperty(0)); // false
console.log(0 in barr);              // false
Run Code Online (Sandbox Code Playgroud)

至:

var arr = Array.apply(null, {length: 10});
console.log(arr.hasOwnProperty(0));  // true
console.log(0 in arr);               // true
Run Code Online (Sandbox Code Playgroud)

并且Array.apply工作是因为它询问{length: 10}它的属性0是什么,接收undefined,并因此分配它正在构建的数组undefined的属性0,等等.我的推理是否正确?

是的,虽然要清楚,但这apply是在询问什么属性0,然后它在调用时使用它作为第一个参数Array.Array然后它接受第一个参数的值并将其分配给0它正在创建的数组上的属性.

是否真的没有那么简单的方法来定义一个数组,该数组包含其范围内每个索引的未定义整数属性,而不是根本没有整数属性?

只是轻微:ES2015添加Array.from,它接受类似数组的对象并返回一个真实数组(可选择映射条目).那就是:

var arr = Array.from({length:10});
Run Code Online (Sandbox Code Playgroud)

很少需要这样做,而不是简单a = new Array(bigNumberHere);a = []; a.length = bigNumberHere.例如,很多时候您并不关心该属性是否存在或是否存在该值undefined.有时候你这样做,但是为了给你提供观点,我已经专业写了20年的JavaScript,相当密集地写了最后的8年,我可能很关心,哦,一次或两次,顶部.

你提到在你正在处理的特定情况下,它与之结合map,因此Array.from取代了两者:

var arr = Array.from({length: 10}, function() { return "hi"; });
Run Code Online (Sandbox Code Playgroud)

...产量

["hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi"]
Run Code Online (Sandbox Code Playgroud)

虽然Array.from是ES2015中的新功能,但它可以在较旧的JavaScript引擎上进行填充/填充.