在javascript中,测试属性是否深深嵌套在对象图中?

时间:2010-12-03 06:26:49

标签: javascript object graph properties

我从CouchDB数据库中获得了一组完全不同的复杂JSON对象。每个都包含许多级别的嵌套属性 - 例如,

tps_report.personnel_info.productivity.units_sold = 8  

我想迭代这些对象并用它们做些事情:例如,

// writes units sold from each TPS report:
for (i in tpsReports) {
  if (tpsReports[i].personnel_info.productivity.units_sold < 10) {
    fireEmployee();
  }
}

问题是许多TPS报告没有设置所有这些属性。因此,如果我尝试这个,我将在第一次循环到达没有“personnel_info”属性的报告时出现错误,从而尝试找到“未定义”的“生产力”属性。我宁愿发生的是条件只是跳过它并继续。

我看到两种解决方法,这两种方式对我来说都很难看

  1. 使用嵌套条件分别测试每个属性
  2. 将该行包含在try / catch块中以捕获错误并忽略它
  3. 我更喜欢的是PHP的isset()函数,不管你输入什么都不会抛出错误 - 它只会告诉你你要查找的特定变量是存在的还是不。所以,像

    // writes units sold from each TPS report:
    for (i in tpsReports) {
      if (isset(tpsReports[i].personnel_info.productivity.units_sold)){
        if (tpsReports[i].personnel_info.productivity.units_sold < 10) {
          fireEmployee();
        }
      }
    }
    

    有什么想法吗?

6 个答案:

答案 0 :(得分:5)

function isset(obj, propStr) {
    var parts = propStr.split(".");
    var cur = obj;
    for (var i=0; i<parts.length; i++) {
        if (!cur[parts[i]])
            return false;
        cur = cur[parts[i]];
    }
    return true;
}

请注意,第二个参数是一个字符串,因此在访问不存在的属性上的属性时不会抛出异常。

答案 1 :(得分:2)

Theres定义了一个函数on this blog来安全地从JS对象中读取嵌套属性

它允许您挖掘对象的属性......即

safeRead(tps_report, 'personnel_info', 'productivity', 'units_sold');

如果对象链的任何部分为null或未定义,则返回空字符串....

答案 2 :(得分:2)

/**
 * units sold from each TPS report
 */

var units;

// the hard way
units = (report && report.personnel && report.personnel.info &&
        report.personnel.info.sales && report.personnel.info.sales.units &&
        report.personnel.info.sales.units.sold) || 0;

// the easy way
units = selectn('personnel.info.sales.units.sold', report) || 0;

// resulting action
if (units < 10) fireEmployee();

无耻的插件:我是selectn的作者。它可以通过npm install selectnbower install selectncomponent install wilmoore/selectn来获取。

查看自述文件中的示例,找出为什么这比isset克隆更好。您还可以将其用作filter谓词,以便擦除不包含特定深层嵌套属性的嵌套对象。

答案 3 :(得分:1)

您可以使用我的ObjectPath查询大型嵌套JSON文档。我正在构建它的原因是在编程语言中缺乏使用JSON的好工具,就像问题中提到的那样。

该项目是开源的,并且在AGPL许可下。

http://adriank.github.io/ObjectPath/

Javascript实现没有经过优化,缺少一半的Python功能,但我很想在社区需要的时候添加新内容 - 只需告诉我你对什么是至关重要的。

答案 4 :(得分:0)

我非常喜欢jsonpath的优雅,相当于xpath,但是对于json。

http://goessner.net/articles/JsonPath/

你可以在这里做一个表达式:

var units_sold = jsonPath(tpsResports, '$.[*].personnel_info.productivity.units_sold');
// units_sold is array of found values... 

(我没有仔细检查我的表情,你的例子中你想要的可能是错的)

答案 5 :(得分:0)

丑陋的方式:

for (i in tpsReports) {
  try {
    if(tpsReports[i].personnel_info.productivity.units_sold < 10) {
      fireEmployee();
    }
  } catch (e) {}
}