Javascript: for..in loop works longer than expected

In the following code, the actual length of user.roles is 1. However, the loop runs twice.

When I print the value of i, it displays as "diff" for the second iteration. Switching to the usual solution to the situation for the cycle. However, I would like to know what the problem is with the for..in loop .

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: the user is an object, and the roles are an array of objects. An example of the roles that caused the problem is shown below:

 { "_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 }, ] } ], } 
+6
source share
2 answers

user.roles is represented as an array. And for an array you should not use for.

Simple example

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

From MDN , the for ... in operator iterates over the enumerated properties of the object in random order. For each individual property, operators can be executed.

How to choose iterator type, here is iterators link

EDIT

According to the updated question, the above can only have the diff property, if somewhere in the code below

 Array.prototype.diff = ..... 
+2
source

I think this is what you are looking for. I believe your accessTypes is an array containing the following elements:

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

Edited to increase efficiency.

 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 accepts an iterator function. An iterator function is called for each record in the array to skip non-existent records in sparse arrays.

forEach also has the advantage that you do not need to declare indexing and variable values ​​in the content area, as they are supplied as arguments to the iteration function and are so well attached to this iteration.

If you are worried about the cost of executing a function call for each array entry, you should not; more technical details .

If you still get the impression that forEach significantly slower, you can use a simple for loop, as I explain in my other answers .

Hope this helps you.

+2
source

Source: https://habr.com/ru/post/1012401/


All Articles