2016-11-17 36 views
6

在以下代碼中,user.roles的實際長度爲1.但是,循環運行兩次。Javascript:for..in循環運行的次數比預期的多

當我輸出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; 
           } 
          } 
         } 
        } 
       } 
      } 

更新:用戶是一個對象,角色是一個對象數組。導致此問題的角色的實例如下所示:

{ 
    "_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 
     }, 

     ] 
    } 
    ], 
} 
+0

你能定義用戶,角色,權限,accessType嗎?那些是對象,字符串,整數。 – Teocci

+0

'user.roles'是一個Array/Iterator嗎?也許你應該使用'for .. of' – zeronone

+0

爲什麼你使用'for in'?嘗試使用'forEach'。它更方便。 http://stackoverflow.com/questions/23614054/javascript-nuances-of-myarray-foreach-vs-for-loop –

回答

2

user.roles似乎是一個數組。而對於數組,你不應該使用在。

簡單的例子

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

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

MDN的對... in語句遍歷對象的枚舉的屬性,以任意順序。對於每個不同的屬性,可以執行語句。

如何選擇迭代器的類型,這裏是一個參考iterators

編輯

按照更新的問題,上面只有在配備了財產diff某處代碼以下是目前

Array.prototype.diff = ..... 
+0

謝謝。但是,在這種情況下,user.roles似乎只有一個可執行屬性,對吧? 即它只有一個對象。 當我控制** i **的值時,對於第二個(意外的)迭代,它保存值'** diff **'。 –

+0

如果是這種情況,那麼代碼中必須有'Array.prototype.diff'。 – nikhil

+0

@AllenGJ - 你檢查了嗎?另外,你可以通過刪除Array.prototype.diff來刪除它。 – nikhil

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中所解釋的那樣。

希望這可以幫助你。

+0

性能如何?我的印象是,forEach從根本上來說比較慢。 –

+0

@AllenGJ如果你仍然覺得'forEach'基本上比較慢,你可以使用一個簡單的'for'循環來解釋另一個[Answer](http://stackoverflow.com/questions/40647538/#40647652)。 – Teocci