【问题标题】:Difference between access to mapped objects in array through for cycle/for in cycle通过for循环/for循环访问数组中映射对象的区别
【发布时间】:2013-09-30 20:50:55
【问题描述】:

我一直在使用 D3.js 库,但遇到了这个对我来说未知的行为。我使用范围函数创建了包含 0 到 99 的 100 个数字的数组,然后将函数映射到数组的每个成员,如下所示:

var data = d3.range(100).map(function() {
    return {
        x: 0,
        y: 0
    };
})

在关于 javascript 的 Mozilla 文档中是这个映射函数行为描述:

使用对该数组中的每个元素调用提供的函数的结果创建一个新数组。

我的预期是,在执行此代码后,我的变量数据将是一个包含 100 个对象的数组,每个对象的 x 和 y 属性都设置为 0。

我尝试使用两种不同的方法访问这些对象。起初,我尝试像这样使用 for/in 循环:

for(d in data){
  console.log(d);
  console.log(d.x + " " + d.y);
}

这个循环的输出是:

0
undefined undefined
1
undefined undefined
...
99
undefined undefined

然后我尝试使用这样的循环通过索引访问每个对象

for(var i = 0; i < data.length; i++){
    console.log(data[i]);
    console.log(data[i].x + " " + data[i].y);
}

突然之间,输出完全不同了,找到并匹配所有对象及其属性:

[object Object]
0 0
[object Object]
0 0
...
[object Object]
0 0

我不明白为什么通过 for/in 循环访问数组中的对象不起作用,但直接索引访问是成功的。我想我可能遗漏了一些关于 map 函数如何将函数结果映射到原始数组的内容,或者可能 for/in 循环访问数组与通过索引不同。有谁知道为什么会这样?谢谢。

【问题讨论】:

    标签: javascript arrays d3.js


    【解决方案1】:

    for..in 迭代数组索引,而不是值:

    > a = [100,200,300]
    [100, 200, 300]
    > for(d in a) console.log(d)
    0
    1
    2
    

    所以,在您的第一个循环中,您需要:

    for(d in data)
        console.log(data[d].x + " " + data[d].y);
    

    【讨论】:

    • 标准免责声明在这里适用:避免在数组上使用for..in,因为它会遍历任何可枚举的属性(如 polyfill 和其他添加到 Array.prototype 的东西)。通常建议在循环中使用hasOwnProperty 检查。
    【解决方案2】:

    如你所说,

    var data = d3.range(100).map(function() {
        return {
            x: 0,
            y: 0
        };
    })
    

    使用对该数组中的每个元素调用提供的函数的结果创建一个新数组。

    for in 可用于非数组的对象。

    对于需要使用for循环的数组。

    你可以关注这个

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-11
      • 2021-09-21
      • 2015-02-25
      • 1970-01-01
      • 2021-07-28
      • 2018-06-09
      • 1970-01-01
      • 2011-02-11
      相关资源
      最近更新 更多