Javascript:for..in 循环运行的次数超出预期
Posted
技术标签:
【中文标题】Javascript:for..in 循环运行的次数超出预期【英文标题】:Javascript: for..in loop running more number of times than expected 【发布时间】:2017-03-31 14:31:12 【问题描述】:在下面的代码中,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
,
]
],
【问题讨论】:
你能定义用户、角色、权限、访问类型吗?这些是对象、字符串、整数。user.roles
是一个数组/迭代器吗?也许你应该使用for .. of
你为什么使用for in
?尝试使用 forEach
。它更方便。 ***.com/questions/23614054/…
@Teocci user.roles 是对象数组,权限是 user.roles 中的对象数组。 accessType 是一个字符串数组。
@AllenGJ 你能把我的问题标记为答案吗?
【参考方案1】:
user.roles
似乎是一个数组。而对于数组,你不应该使用 for in。
简单示例
var arr = [2];
arr.s = 3;
for (var i in arr)
console.log("here"); // paints twice
来自MDN,for...in 语句以任意顺序迭代对象的可枚举属性。对于每个不同的属性,可以执行语句。
如何选择迭代器的类型,这里参考iterators
编辑
根据更新后的问题,如果以下代码中的某处存在,则上述内容只能带有 diff
属性
Array.prototype.diff = .....
【讨论】:
谢谢。但是,在这种情况下, user.roles 似乎只有一个可编号的属性,对吧?即,它只有一个对象。当我控制 i 的值时,对于第二次(意外)迭代,它保存值 'diff'。 如果是这种情况,那么您的代码中一定有Array.prototype.diff
。
@AllenGJ - 你检查了吗?此外,您可以通过delete Array.prototype.diff;
将其删除【参考方案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 中解释的那样。
希望对您有所帮助。
【讨论】:
性能怎么样?我的印象是 forEach 从根本上来说更慢。 @AllenGJ 如果您仍然觉得forEach
速度较慢,您可以使用一个简单的for
循环,正如我在另一个Answer 中解释的那样。以上是关于Javascript:for..in 循环运行的次数超出预期的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript-//FOR/IN循环。当使用for/in循环遍历关联数组时,就可以清晰地体会到for/in的强大之处。