在JavaScript中为空数组使用a for each循环

时间:2014-12-11 21:52:03

标签: javascript

我发现在javascript中我不能在空数组上使用a。任何人都可以向我解释为什么会这样吗?

我在javascript中初始化了一个数组:

var arr = new Array(10);

当我对阵列上的每个循环使用a时没有任何反应:

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

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

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

我认为,由于数组中的每个项都是未定义的,因此它甚至不执行forEach。我认为它仍然会遍历未定义的项目。谁能解释为什么会这样? 这个问题并不是要问如何最有效地用零填充数组,它会询问有关每个循环和空数组的交互的详细信息

6 个答案:

答案 0 :(得分:20)

如果将阵列初始化修改为:

,则可以像预期的那样使用forEach
var arr = Array.apply(null, Array(10))

然后你可以做一个类似的预告:

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

结果是:

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

答案 1 :(得分:15)

你中途对了!

  

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

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

来自MDNScreenshot from MDN regarding forEach

答案 2 :(得分:4)

.forEach为数组中的每个元素运行函数。设置i的值什么都不做,它不是参考。

只需使用正常的for循环:

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

或者不是做new Array(10),而是做:

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

答案 3 :(得分:3)

基于Faris Zacina answer,一线方法。

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

答案 4 :(得分:1)

如果我对此错误,我希望有人能纠正我。

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

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

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

现在JS数组只是一个带有编号属性的花哨对象。即

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

另一种思考上述数组的方法是将其视为像这样的对象

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

但是,如果您使用其他表单构建数组,则可以得到:

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

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

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

答案 5 :(得分:0)

控制什么是“被淘汰”

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

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

这里我们过滤了奇怪的指标。

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

这样的策略也可以让你进入其他行为,

如果不是k%2===0,而是

  • true你会击中所有空白区域。
  • k != undefined允许您仅迭代定义的值。
  • k in arr会将您带回到您开始的地方。

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