This question already has an answer here:
这个问题在这里已有答案:
- JavaScript “new Array(n)” and “Array.prototype.map” weirdness 12 answers
- forEach on array of undefined created by Array constructor 2 answers
JavaScript“new Array(n)”和“Array.prototype.map”怪异12个答案
forEach由Array构造函数2答案创建的未定义数组
I'm want to quickly construct an array of n
length using the array constructor Array()
and then loop over the resulting array.
我想使用数组构造函数Array()快速构造一个n长度的数组,然后遍历生成的数组。
Per MDN's docs:
根据MDN的文档:
If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with length set to that number. If the argument is any other number, a RangeError exception is thrown.
如果传递给Array构造函数的唯一参数是0到232-1(含)之间的整数,则返回一个长度设置为该数字的新JavaScript数组。如果参数是任何其他数字,则抛出RangeError异常。
Presumably, executing Array(5)
creates an array with a length of 5, which it does.
据推测,执行Array(5)会创建一个长度为5的数组。
var arr = new Array(5);
console.log(arr); // [undefined x 5]
console.log(arr.length); // 5
However, when I try to loop over the resulting array and log out the values or the index, nothing happens.
但是,当我尝试循环结果数组并注销值或索引时,没有任何反应。
arr.forEach(function(v, i) { console.log(v, i); });
// nothing logs to the console
Alternatively, if I use an array literal, and try to loop over the values, it logs as expected:
或者,如果我使用数组文字,并尝试循环值,它会按预期记录:
[undefined, undefined].forEach(function(v, i) { console.log(v, i); });
// undefined 0
// undefined 1
Why can't I loop over an array created by the Array constructor?
为什么我不能遍历由Array构造函数创建的数组?
This answer explains some of the browser strangeness that occurs with map
, example:
这个答案解释了地图中出现的一些浏览器异常,例如:
arr.map(function(v, i) { return i; }) // returns [undefined x 5]
But I'm particularly interested in why the forEach
loop doesn't iterate at all over the values.
但是我特别感兴趣的是为什么forEach循环不会迭代值。
4 个解决方案
#1
4
I understand I am not answering to the question directly, bit still I believe this provides good information.
我知道我没有直接回答这个问题,我仍然认为这提供了很好的信息。
Check what Kyle Simpson said recently about this topic.
查看Kyle Simpson最近谈到的关于这个话题的内容。
Basically,
console.log(new Array(5)) // Chrome: [undefinedx5] Firefox: [ <5 empty slots> ]
and
console.log([undefined, undefined, undefined, undefined, undefined]) // [ undefined, undefined, undefined, undefined, undefined ]
are entirely different value types. And the browser is (kind of) lying to you when it says undefinedx5. Applying .map() over the first case will return nothing, while in the second case you can do operations with the undefined.
是完全不同的价值类型。当浏览器显示undefinedx5时,浏览器会对你说谎。在第一种情况下应用.map()将不返回任何内容,而在第二种情况下,您可以使用undefined进行操作。
From the spec, ecma-262/5.1/#sec-15.4.2.2, the only thing new Array(5)
does, is to create an object of class type Array with length property = 5. The literal array syntax, [], actually places the types (if you give it something) in the slots.
根据规范,ecma-262 / 5.1 /#sec-15.4.2.2,新的Array(5)所做的唯一事情就是创建一个类型为Array的对象,其长度为property = 5.文字数组语法[],实际上在插槽中放置类型(如果你给它一些东西)。
#2
3
That's because ES5 array methods skip missing indexes. That is, they iterate i
from 0
to length-1
, but at each iteration they check if the array has an i
own property.
那是因为ES5数组方法跳过了缺失的索引。也就是说,它们将i从0迭代到长度为1,但在每次迭代时,它们检查数组是否具有i属性。
If you want it to work, you can use fill
to create the indices.
如果您希望它工作,您可以使用填充来创建索引。
var arr = new Array(5).fill();
arr.forEach(function(v, i) { console.log('arr['+i+'] = ' + v); });
#3
2
Looks like you have a typo in your code:
看起来您的代码中有拼写错误:
arr.forEach(functio(v, i) {
Use this instead:
改为使用它:
arr.forEach(function(v, i) {
UPDATE
forEach() executes the provided callback once for each element present in the array in ascending order. It is not invoked for index properties that have been deleted or are uninitialized (i.e. on sparse arrays). MDN article
forEach()按升序为数组中的每个元素执行一次提供的回调。对于已删除或未初始化的索引属性(即在稀疏数组上),不会调用它。 MDN文章
#4
-1
I suspect that this may have to do with intricacies of the Javascript foreach loop, not the Array(int) constructor. Using a normal for loop:
我怀疑这可能与Javascript foreach循环的复杂性有关,而不是Array(int)构造函数。使用正常for循环:
for(var i = 0; i < arr.length; i += 1) {
console.log(arr[i] + " " + i);
}
produced the desired result.
产生了预期的结果。
#1
4
I understand I am not answering to the question directly, bit still I believe this provides good information.
我知道我没有直接回答这个问题,我仍然认为这提供了很好的信息。
Check what Kyle Simpson said recently about this topic.
查看Kyle Simpson最近谈到的关于这个话题的内容。
Basically,
console.log(new Array(5)) // Chrome: [undefinedx5] Firefox: [ <5 empty slots> ]
and
console.log([undefined, undefined, undefined, undefined, undefined]) // [ undefined, undefined, undefined, undefined, undefined ]
are entirely different value types. And the browser is (kind of) lying to you when it says undefinedx5. Applying .map() over the first case will return nothing, while in the second case you can do operations with the undefined.
是完全不同的价值类型。当浏览器显示undefinedx5时,浏览器会对你说谎。在第一种情况下应用.map()将不返回任何内容,而在第二种情况下,您可以使用undefined进行操作。
From the spec, ecma-262/5.1/#sec-15.4.2.2, the only thing new Array(5)
does, is to create an object of class type Array with length property = 5. The literal array syntax, [], actually places the types (if you give it something) in the slots.
根据规范,ecma-262 / 5.1 /#sec-15.4.2.2,新的Array(5)所做的唯一事情就是创建一个类型为Array的对象,其长度为property = 5.文字数组语法[],实际上在插槽中放置类型(如果你给它一些东西)。
#2
3
That's because ES5 array methods skip missing indexes. That is, they iterate i
from 0
to length-1
, but at each iteration they check if the array has an i
own property.
那是因为ES5数组方法跳过了缺失的索引。也就是说,它们将i从0迭代到长度为1,但在每次迭代时,它们检查数组是否具有i属性。
If you want it to work, you can use fill
to create the indices.
如果您希望它工作,您可以使用填充来创建索引。
var arr = new Array(5).fill();
arr.forEach(function(v, i) { console.log('arr['+i+'] = ' + v); });
#3
2
Looks like you have a typo in your code:
看起来您的代码中有拼写错误:
arr.forEach(functio(v, i) {
Use this instead:
改为使用它:
arr.forEach(function(v, i) {
UPDATE
forEach() executes the provided callback once for each element present in the array in ascending order. It is not invoked for index properties that have been deleted or are uninitialized (i.e. on sparse arrays). MDN article
forEach()按升序为数组中的每个元素执行一次提供的回调。对于已删除或未初始化的索引属性(即在稀疏数组上),不会调用它。 MDN文章
#4
-1
I suspect that this may have to do with intricacies of the Javascript foreach loop, not the Array(int) constructor. Using a normal for loop:
我怀疑这可能与Javascript foreach循环的复杂性有关,而不是Array(int)构造函数。使用正常for循环:
for(var i = 0; i < arr.length; i += 1) {
console.log(arr[i] + " " + i);
}
produced the desired result.
产生了预期的结果。