2010-03-30 105 views
37

有沒有一種方法(在jQuery或JavaScript中)循環通過每個對象,它的子代和孫輩等?循環遍歷一個對象(樹)遞歸地

如果是的話......我還可以讀他們的名字嗎?

例子:

foo :{ 
    bar:'', 
    child:{ 
    grand:{ 
     greatgrand: { 
     //and so on 
     } 
    } 
    } 
} 

所以循環應該做這樣的事情...

loop start 
    if(nameof == 'child'){ 
    //do something 
    } 
    if(nameof == 'bar'){ 
    //do something 
    } 
    if(nameof =='grand'){ 
    //do something 
    } 
loop end 

回答

58

您正在尋找的for...in循環:

for (var key in foo) 
{ 
    if (key == "child") 
     // do something... 
} 

要知道for...in循環會迭代任何可枚舉的屬性,包括那些添加到對象原型的屬性。爲了避免作用於這些特性,你可以使用hasOwnProperty方法來檢查,看看是否財產只屬於該對象:

for (var key in foo) 
{ 
    if (!foo.hasOwnProperty(key)) 
     continue;  // skip this property 
    if (key == "child") 
     // do something... 
} 

執行環路遞歸可以像寫一個遞歸函數一樣簡單:

// This function handles arrays and objects 
function eachRecursive(obj) 
{ 
    for (var k in obj) 
    { 
     if (typeof obj[k] == "object" && obj[k] !== null) 
      eachRecursive(obj[k]); 
     else 
      // do something... 
    } 
} 
+2

@val:這將是困難的崩潰與對象遞歸的瀏覽器。該對象需要包含對自身的引用作爲其中一個屬性:-) – 2010-04-02 15:53:06

+1

嘗試:'(a = {})._ = a' – Annan 2014-07-01 22:50:10

+3

@Annan:是的,這或多或少是我所掌握的。這一點根本就不是這樣做的;-) – 2014-07-02 09:29:58

0

如果你想找回關係樹,你可以遞歸地使用Object.keys。

function paths(item) { 
 
    function iter(r, p) { 
 
    var keys = Object.keys(r); 
 
    if (keys.length) { 
 
     return keys.forEach(x => iter(r[x], p.concat(x))); 
 
    } 
 
    result.push([p]) 
 
    } 
 
    var result = []; 
 
    iter(item, []); 
 
    return result; 
 
} 
 

 
var data = { 
 
    foo: { 
 
    bar: '', 
 
    child: { 
 
     grand: { 
 
     greatgrand: {} 
 
     } 
 
    } 
 
    } 
 
} 
 

 
console.log(paths(data));