如何在javascript中获取对象的孩子的孩子。 (如果存在)

时间:2011-11-19 12:30:48

标签: javascript arrays json

我得到了一些json数据,我有这样的结构:

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

我需要获取某些页面的所有模块。

输入参数为categorysectionpage

所以我需要获得模块[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 []的调用。有更好(更快)的方法吗?

3 个答案:

答案 0 :(得分: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) || [];

答案 1 :(得分: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'])

答案 2 :(得分: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/