2011-11-19 61 views
1

我得到一些JSON數據,在那裏我有這樣的結構:如何在javascript中獲取對象的小孩的孩子。 (如果存在)

'modules' : { 
    'category1' : { 
     'section1' : { 
      'page1' : [ 'module1', 'module2' ] 
     }, 
     'section2' : { 
      'page1' : [ 'module1' ] 
     } 
    }, 
    // and so on 
} 

我需要一些網頁的所有模塊。

輸入參數是category,sectionpage

所以我需要獲取模塊[category] ​​[section] [page]。

但是如果沒有這樣的部分或頁面的模塊會怎麼樣。

// m = getAllModules(); 

    if (m.hasOwnProperty(category)) { 
     if (m[category].hasOwnProperty(section)) { 
      if (m[category][section].hasOwnProperty(page)) { 
       concrete = m[category][section][page]; 
      } 
     } 
    } 

如何優化此腳本?這是很多m []的調用。有沒有更好(更快)的方法來做到這一點?

回答

5

你可以做這樣的:

var categories, sections;  
if ((categories = modules[categoryName]) && (sections = categories[sectionName])) { 
    concrete = sections[pageName] || []; 
} 
else { 
    concrete = []; 
} 

您還可以創建一個更通用的解決方案:

function traverse(source) { 
    var path = Array.prototype.slice.call(arguments, 1); 
    var current = source; 
    for (var i = 0, l = path.length; i < l; ++i) { 
    current = current[path[i]]; 
    if (!current) break; 
    } 
    return current; 
} 

使用方法如下:

concrete = traverse(modules, categoryName, sectionName, pageName) || []; 
2

嗯,你可以使其成爲遞歸函數,儘管這可能會更慢。儘管這很容易理解,並且可以重用。

function getFromJSON(object, listOfPropertyNames) { 
    if (listOfPropertyNames.length == 0 || object == undefined) { 
     return object; 
    } 
    var propertyToFind = listOfPropertyNames[0]; 
    if (object.hasOwnProperty(propertyToFind)) { 
     return getFromJSON(object[propertyToFind], listOfPropertyNames.slice(1)); 
    } 
} 

concrete = getFromJSON(m, ['category','section','page']) 
1

考慮爲這樣的一個效用函數:

function grab(val, names) { 
    names = names.split('.');  
    while (val && names.length) { val = val[ names.shift() ]; }  
    return val; 
} 

用法:

grab(m, 'category1.section1.page1') // returns [ 'module1', 'module2' ] 
grab(m, 'category7.section1.page1') // returns undefined 

現場演示:http://jsfiddle.net/2f6Ae/5/