2010-03-30 12 views
37

Czy istnieje sposób (w jQuery lub JavaScript), aby przechodzić przez każdy obiekt, a to dzieci i wnuki i tak dalej?Zapętlanie obiektu (drzewa) rekurencyjnie

Jeśli tak, to czy mogę również przeczytać ich imię?

Przykład:

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

więc pętla powinna zrobić coś takiego ...

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

Odpowiedz

58

Patrzysz na for...in pętli:

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

Be świadomy, że będą pętle for...in iteruj po dowolnych właściwościach przeliczalnych, w tym tych, które są dodawane do prototypu obiektu. Aby uniknąć działając na te właściwości, można użyć metody hasOwnProperty aby sprawdzić, czy nieruchomość należy tylko do tego obiektu:

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

wykonując pętlę rekurencyjnie może być tak proste, jak pisanie funkcji rekurencyjnej:

// 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: trudno byłoby crash przeglądarki z obiektu rekursji. Obiekt musiałby zawierać odniesienie do siebie jako jednej z właściwości :-) –

+1

try: '(a = {}) ._ = a'' – Annan

+3

@Annan: tak, to jest mniej więcej to, do czego dążyłem. Chodziło o to, żeby tego nie robić ;-) –

0

Jeśli chcesz odzyskać drzewo relacji, możesz używać rekurencyjnie 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));