2010-03-30 149 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));