Javascript:for..in循环运行的次数比预期的多

时间:2016-11-17 06:42:05

标签: javascript arrays node.js for-loop

在下面的代码中,user.roles的实际长度为1.但是,循环运行两次。

当我输出i的值时,它显示为' diff'对于第二次迭代。 切换到普通for循环解决了这种情况。 但是,我想知道 for..in 循环的问题是什么。

 for (var i in user.roles) {
                if (user.roles[i].school.equals(schoolId)) {
                    for (var j in user.roles[i].permissions) {
                        for (var k in accessType) {
                            if (user.roles[i].permissions[j].feature == featureKey) {
                                if (user.roles[i].permissions[j][accessType[k]]) {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }

更新:用户是一个对象,角色是一个对象数组。导致该问题的角色实例如下所示:

{
  "_id": "582d3390d572d05c1f028f53",
  "displayName": "Test Teacher Attendance",
  "gender": "Male",
  "roles": [
    {
      "_id": "57a1b3ccc71009c62a48a684",
      "school": "57a1b3ccc71009c62a48a682",
      "role": "Teacher",
      "__v": 0,
      "designation": true,
      "permissions": [
        {
          "feature": "User",
          "_id": "57ac0b9171b8f0b82befdb7d",
          "review": false,
          "view": true,
          "delete": false,
          "edit": false,
          "create": false
        },
        {
          "feature": "Notice",
          "_id": "57ac0b9171b8f0b82befdb7c",
          "review": false,
          "view": true,
          "delete": false,
          "edit": false,
          "create": false
        },

      ]
    }
  ],
}

2 个答案:

答案 0 :(得分:2)

user.roles似乎是一个数组。对于数组,你不应该用于。

简单示例

var arr = [2];
arr.s = 3;

for (var i  in arr) {
console.log("here"); // paints twice
}

MDN for ... in语句以任意顺序迭代对象的可枚举属性。对于每个不同的属性,可以执行语句。

如何选择迭代器的类型,这里是引用iterators

修改

根据更新后的问题,如果以下代码中的某处存在,上述内容只能带有diff属性

Array.prototype.diff = .....

答案 1 :(得分:2)

我认为这就是你要找的东西。 我假设您的accessTypes是一个包含以下项目的数组:

var accessTypes = ["review", "view", "delete", "edit", "create"];

已编辑以提高效率。



var schoolId = "57a1b3ccc71009c62a48a682";
var featureKey = "Notice";
var accessTypes = ["review", "view", "delete", "edit", "create"];

var user = {
  "_id": "582d3390d572d05c1f028f53",
  "displayName": "Test Teacher Attendance",
  "gender": "Male",
  "roles": [{
    "_id": "57a1b3ccc71009c62a48a684",
    "school": "57a1b3ccc71009c62a48a682",
    "role": "Teacher",
    "__v": 0,
    "designation": true,
    "permissions": [{
      "feature": "User",
      "_id": "57ac0b9171b8f0b82befdb7d",
      "review": false,
      "view": true,
      "delete": false,
      "edit": false,
      "create": false
    }, {
      "feature": "Notice",
      "_id": "57ac0b9171b8f0b82befdb7c",
      "review": false,
      "view": true,
      "delete": false,
      "edit": false,
      "create": false
    }]
  }]
};

user.roles.forEach(function(roleItem) {
  // console.log('This is a role: ' + roleItem.school);
  if (roleItem.school == schoolId) {
    roleItem.permissions.forEach(function(permissionItem) {
      // console.log('This is a permission: ' + permissionItem.feature);
      // console.log('This is a accessType: ' + accessType);
      if (permissionItem.feature == featureKey) {
        accessTypes.forEach(function(accessType) {
          if (permissionItem[accessType]) {
            console.log('accessType: ' + accessType + ' -> true');
            return true;
          }
        });
      }
    });
  }
});




forEach接受迭代器函数。为数组中的每个条目调用迭代器函数,按顺序跳过稀疏数组中不存在的条目。

forEach还有一个好处,就是你不必在包含范围内声明索引和值变量,因为它们作为迭代函数的参数提供,所以很好范围只是那个迭代。

如果您担心为每个阵列条目调用函数的运行时成本,请不要这样做;更多technical details

如果您仍然认为forEach基本上较慢,则可以使用简单的for循环,因为我在另一个my answers中进行了解释。

希望这会对你有所帮助。