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()是无用的.
所以从我所知道的,它调用Array()好像它传递了10个参数,但由于它没有定义任何这些"整数属性",所以就好像它传递了10个未定义的参数.那是对的吗?
对,就是这样.这样做:
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
Run Code Online (Sandbox Code Playgroud)
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';}));我想知道为什么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具有没有项和length的10.所以在第一个,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引擎上进行填充/填充.