Javascript:.In循环运行的次数多于预期

Javascript: for..in loop running more number of times than expected

本文关键字:于预期 运行 In 循环 Javascript      更新时间:2023-09-26

在下面的代码中,用户的实际长度。"Roles"为1。然而,循环运行两次。

当我输出I的值时,它在第二次迭代中显示为'diff'。切换到普通的for循环解决了这种情况。然而,我想知道问题是什么与为…在循环。

 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;
                                }
                            }
                        }
                    }
                }
            }

Update: user是一个对象,roles是一个对象数组。导致这个问题的角色实例如下所示:

{
  "_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似乎是一个数组。对于数组,你不应该使用for in.

简单例子
var arr = [2];
arr.s = 3;
for (var i  in arr) {
console.log("here"); // paints twice
}

From MDN, The for…In语句以任意顺序遍历对象的可枚举属性。

如何选择迭代器的类型,这里有一个参考迭代器

编辑

根据更新的问题,如果以下代码中的某个地方存在

,则上述内容只能带有属性diff
Array.prototype.diff = .....

我想这就是你要找的。我假设您的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的另一个好处是,您不必在包含范围内声明索引和值变量,因为它们是作为迭代函数的参数提供的,因此很好地将作用域限定在该迭代中。

如果你担心为每个数组项调用函数的运行时成本,不必担心;更多技术细节

如果你仍然觉得forEach基本上比较慢,你可以使用一个简单的for循环,正如我在另一个答案中解释的那样。