在 JavaScript 中的空数组上使用 for each 循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27433075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:08:29  来源:igfitidea点击:

Using a for each loop on an empty array in JavaScript

javascript

提问by Craig

I've found that I can't use a for each loop on an empty array in javascript. Can anyone explain to me why this is?

我发现我不能在 javascript 中的空数组上使用 for each 循环。谁能向我解释这是为什么?

I've initialized an array in javascript like so:

我已经在 javascript 中初始化了一个数组,如下所示:

var arr = new Array(10);

when I use a for each loop on the array nothing happens:

当我在数组上为每个循环使用 a 时,什么也没有发生:

arr.forEach(function(i) {
    i = 0;
});

the result is still an array of undefined values:

结果仍然是未定义值的数组:

arr = [ , , , , , , , , , ];

I think that maybe since each item in the array is undefined, it doesn't even execute the forEach. I would think that it would still iterate through the undefined items. Can anyone explain why this is occurring? This question is not asking how to most efficiently fill an array with zeros, it's asking details on the interaction of a for each loop and an empty array.

我认为可能因为数组中的每个项目都是未定义的,它甚至不执行 forEach。我认为它仍然会遍历未定义的项目。谁能解释为什么会发生这种情况?这个问题不是问如何最有效地用零填充数组,而是询问有关 a for each 循环和空数组的交互的详细信息

采纳答案by Adam

You're half-way right!

你说对了一半!

I think that maybe since each item in the array is undefined, it doesn't even execute the forEach.

我认为可能因为数组中的每个项目都是未定义的,它甚至不执行 forEach。

Array.prototype.forEach does not visit indices which have been deleted or elided; this is a process called ellision. So, it executes, but skips over every element.

Array.prototype.forEach 不访问已删除或省略的索引;这是一个称为ellision的过程。因此,它会执行,但会跳过每个元素。

From MDN: Screenshot from MDN regarding forEach

来自MDN来自 MDN 的关于 forEach 的截图

回答by Faris Zacina

You can use a forEach like you intended if you modify the array initialization to be:

如果将数组初始化修改为:

var arr = Array.apply(null, Array(10))

And then you can do a foreach like:

然后你可以做一个 foreach 像:

arr.forEach(function(el, index) {
    arr[index] = 0;
});

The result is:

结果是:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

回答by Rocket Hazmat

.forEachruns your function for each element in the array. Setting the value of idoes nothing, it's not a reference.

.forEach为数组中的每个元素运行您的函数。设置值i没有任何作用,它不是参考。

Just use a normal forloop:

只需使用普通for循环:

for(var i = 0; i < arr.length; i++){
    arr[i] = 0;
}

Or instead of doing new Array(10), you can just do:

或者不做new Array(10),你可以做:

var arr = [];
for(var i = 0; i < 10; i++){
    arr[i] = 0;
}

回答by Mark E

Based on Faris Zacina answer, a one line approach.

基于Faris Zacina 的回答,一种单行方法。

var zeros = Array.apply(null, Array(10)).map(function(){return 0})

回答by derp

I hope someone can correct me if i'm wrong about this

如果我错了,我希望有人可以纠正我

Inside the V8 source code array.js:1042, I found this:

在 V8 源代码array.js:1042 中,我发现了这个:

for (var i = 0; i < length; i++) {
      if (i in array) {
        var element = array[i];
        f(element, i, array);
      }
      //...

The important bit is the condition check using the 'in' operator to determine whether or not to execute the function argument passed into the forEach. The in operator checks for the existence of properties inside an object.

重要的一点是使用“in”运算符进行条件检查,以确定是否执行传递给 forEach 的函数参数。in 运算符检查对象内是否存在属性。

Now a JS array is simply a fancy object with numbered properties. Ie

现在一个 JS 数组只是一个带有编号属性的奇特对象。IE

var array = [undefined,undefined,undefined];
Object.keys(array); // ["0", "1", "2"]

Another way of thinking about the above array is by thinking of it as an object like this

考虑上述数组的另一种方式是将其视为这样的对象

{
  "0": undefined,
  "1": undefined,
  "2": undefined
}

However if you use the other form for constructing the array, you get this:

但是,如果您使用其他形式来构造数组,则会得到以下信息:

var array2 = new Array(3);
Object.keys(array2); // []

This is why you will get the following result:

这就是为什么你会得到以下结果:

var array = [undefined,undefined,undefined];
var array2 = new Array(3);

array.forEach(function(){console.log('foo')}); //will print foo three times
array2.forEach(function(){console.log('bar')}); //will print nothing

回答by Space ED

Controlling what is 'elided'

控制什么是“省略”

As mentioned, the key being present is what determines if forEach hits, and the length just decides the range of keys to check.

如前所述,存在的键决定了 forEach 是否命中,而长度仅决定要检查的键的范围。

Another interesting perspective on this is that you can control what is visible to forEach and other iterative methods using a Proxy with has trap.

另一个有趣的观点是,您可以使用带有陷阱的代理来控制 forEach 和其他迭代方法可见的内容。

here we filter the odd indicies.

在这里我们过滤奇数索引。

let arr = ['zero', 'one', 'two', 'four']
arr.length = 6

let arrProxy = new Proxy(arr, { has(arr, k){ return k%2===0 } })

arrProxy.forEach( val => { console.log(val) })
//zero
//two
//undefined

Such a strategy also lets you get to other behaviors,

这样的策略还可以让你了解其他行为,

if instead of k%2===0you had

如果不是k%2===0你有

  • trueyou would hit all the empty space.
  • k != undefinedlets you iterate over defined values only.
  • k in arrtakes you back where you started.
  • true你会击中所有的空白空间。
  • k != undefined仅允许您迭代定义的值。
  • k in arr带你回到你开始的地方。

of course you should use filter in most situations, this is just a demonstration.

当然在大多数情况下你应该使用过滤器,这只是一个演示。