2016-01-22 107 views
1

給定一個Javascript對象,如何遍歷每個屬性並獲取每個節點的完全限定名稱?我想這樣的事情:獲取當前JSON節點的完全限定名稱

var test = { 
    "axes" : [{ 
     "stackType": "100%", 
     "testObject": { 
      "testProperty": "found" 
     }, 
     "minimum": 0 
    }, { 
     "gridColor": "#test", 
     "testArray": [ 
      {"jelly": 2}, {"jam": 3} 
     ], 
     "gridAlpha": 1 
    }] 
}; 

iterate(test); 

function iterate(obj, parents) { 

    if(!parents) { var parents = []; } 

    for (var property in obj) { 

     parents.push(property); 

     if (obj.hasOwnProperty(property)) { 

      if (typeof obj[property] == "object") { 
       iterate(obj[property], parents); 
      } 
      else if (obj[property].constructor == Array) { 
       for (var i = 0; i < obj[property].length; i++) { 
        iterate(obj[property][i], parents); 
       } 
      } 
      else { 
       console.log(parents + " : " + obj[property]); 
      } 

     } 

    } 

} 

但父母數組只是不斷增加。我認爲這是因爲Javascript通過引用而不是按值來處理數組。

我所需的輸出會是這樣的:

axes, 0, stackType : 100% 
axes, 0, testObject, testProperty : found 
axes, 0, minimum : 0 
axes, 1, gridColor: #test 
axes, 1, testArray, 0, jelly: 2 
axes, 1, testArray, 1, jam: 3 
axes, 1, gridAlpha: 1 

而是我剛剛結束了與每一個新的屬性,並將名單永不復位。

回答

3

在你的循環中,你需要創建一個在parents數組中傳入的副本並附加property給它,並在遞歸調用中傳遞它。否則,你只是修改相同的數組。

var test = { 
 
    "axes": [{ 
 
    "stackType": "100%", 
 
    "testObject": { 
 
     "testProperty": "found" 
 
    }, 
 
    "minimum": 0 
 
    }, { 
 
    "gridColor": "#test", 
 
    "testArray": [{ 
 
     "jelly": 2 
 
    }, { 
 
     "jam": 3 
 
    }], 
 
    "gridAlpha": 1 
 
    }] 
 
}; 
 

 
iterate(test); 
 

 
function iterate(obj, parents) { 
 

 
    if (!parents) { 
 
    var parents = []; 
 
    } 
 

 
    for (var property in obj) { 
 

 
    // changed line: 
 
    var path = [].concat(parents, property); 
 

 
    if (obj.hasOwnProperty(property)) { 
 

 
     if (typeof obj[property] == "object") { 
 
     iterate(obj[property], path); // changed 
 
     } else if (obj[property].constructor == Array) { 
 
     for (var i = 0; i < obj[property].length; i++) { 
 
      iterate(obj[property][i], path); // changed 
 
     } 
 
     } else { 
 
     // changed so you can see it without opening the console 
 
     logLine(path.join(', ') + " : " + obj[property]); 
 
     } 
 

 
    } 
 

 
    } 
 
} 
 

 
function logLine(line) { 
 
    // show in console and in HTML 
 
    console.log(line); 
 
    document.getElementById('output').textContent += line + '\n'; 
 
}
<pre id="output"></pre>

+0

嘿,謝謝。這很好。我嘗試了類似的東西,但我認爲我的問題是將緩衝區變量(路徑)放在for循環之外。 這也不是我需要的解決方案,因爲我問了錯誤的問題。如果我給了你上下文(我需要合併兩個對象),你可能會告訴我可以保存迭代並使用jQuery的$ .extend,如下所示: $ .extend(true,object1,object2); 與真正的合併遞歸。我將此標記爲答案,但是爲了防止有人發現這個答案試圖解決我所遇到的同樣問題,請將其作爲答案。 –