如何用其他方式循环遍历JavaScript对象?

5

以下代码可以正常工作,但ESLint插件显示警告:“不允许使用'ForinStatement'”,因此我想改变它以防止警告消息:

    let count = 0;
    for (const key in groups) {
      if (Object.prototype.toString.call(groups[key]) === '[object Object]') {
        if ({}.hasOwnProperty.call(groups[key], 'users')) {
          count += groups[key].users.length;
        }
      }
    }

1
为什么要使用 const key?为什么不用 let 或者 var。另外,{}.hasOwnProperty.call(groups[key], 'users') 可以简写为 groups[key].hasOwnProperty('users') - Rajesh
3
因为循环体内部的“key”不会改变,这是推荐的做法。 - Madara's Ghost
1
Object.keys(groups).forEach 行不行? - evolutionxbox
1
这个问题有点含糊。你可以用Object.valuesObject.entries或者Object.keys结合for..offorEach或者reduce来迭代一个对象。真正的问题是,你是否理解了for..in与这些选项在语义上的不同之处,并且你是否需要for..in才能使你的逻辑正确运行? - CodingIntrigue
1
@Roberrrt,没错!我特别指的是这个答案:https://dev59.com/Umsy5IYBdhLWcg3wzBF4#18202926。 - evolutionxbox
显示剩余8条评论
4个回答

15

如果你的目标只是为了避免ESLint错误,我建议使用Object.keys(obj).forEach()。在我的项目中,我通常采用这种方法。

伪示例:

Object.keys(groups).forEach(key => {
    if (Object.prototype.toString.call(groups[key]) === '[object Object]') {
        if ({}.hasOwnProperty.call(groups[key], 'users')) {
            count += groups[key].users.length;
        }
    }
});

2
谢谢,它完美地工作了。但是为了避免ESLint,你应该将“Object.keys(groups).forEach(key => {”更改为“Object.keys(groups).forEach((key) => {”。 - methis
箭头函数的作用域参数在单个参数时不需要括号:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions不过按你的方式做更整洁,++! - roberrrt-s

3

以下是三种解决方案,具体取决于您需要地图的哪个部分:键、值或键/值对。

如果您不仅需要地图中的键,还需要相应的值,可以选择以下方法:

for (const [key, value] of Object.entries(object)) {
  // ...
}

如果你只需要键:

for (const key of Object.keys(object)) {
  // ...
}

最后,如果你只需要值而不需要键,可以使用以下方法:

for (const value of Object.values(object)) {
  // ...
}

0

您可以使用单行代码进行检查和计数。

let count = Object.keys(groups).reduce((r, key) =>
    r + (('users' in groups[key]) && groups[key].users.length || 0), 0);

顺带一提,你最好使用'users' in groups[key](而不是groups[key].hasOwnProperty('users')),因为否则代码的语义是不同的。 - zerkms

0

我喜欢实现一个it辅助函数来迭代对象:

function* it(obj) {
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      yield [key, obj[key]];
    }
  }
}

然后你可以这样迭代:

for (const [key, value] of it(obj)) {
  if ({}.toString.call(value) === '[object Object]' &&
      value.hasOwnProperty('users')) {
      count += connections[key].users.length;
    }
}

虽然这种方法仍然使用了for..in,但现在它被包含在一个函数中,您可以在ESLint文件中为其设置单个例外。然后您就不需要再次使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接