3

我必须一次又一次地处理代码,例如考虑以下假设示例:

if (node.data.creatures.humans.women.number === Infinity) {
  // do-someting
}

现在,问题是如果节点未定义,则此条件将中断。同样,如果 node.data 未定义,node.data.creatures 未定义等等,它将中断。

所以我最终使用了以下长条件:

if (node && node.data && node.data.creatures && node.data.creatures.humans && node.data.creatures.women && node.data.creatures.humans.women.number === Infinity) {
  // do-someting
}

现在,想象一下我也必须在代码的许多其他部分中使用该 JSON 对象的一部分。

代码突然开始看起来非常难看。由于我提到的第一个条件,有没有更好的方法来避免诸如“无法调用未定义的属性”之类的错误,这样代码看起来也更好。

你如何处理这种情况?

4

3 回答 3

1

这是我正在使用的,它可能不是“最优化”的方式,但是,这对我有用:

walkObject = function(obj, path) {
  var i = 0,
    part = void 0,
    parts = path.split('.');

  while (obj && (part = parts[i++])) {
    obj = obj[part];
  }
  return obj;
};

该方法接受一个对象和一个字符串,其中包含您要测试的属性的点表示法:

// the object
var obj = { a: { b: {c: [1,2,3], d: "aa"} } };

// tests
console.log("a,b,c", walkObject(obj, 'a.b.c')); // [1,2,3]
console.log("a,b,e", walkObject(obj, 'a.b.e')); // undefined
console.log("z,b,e", walkObject(obj, 'z.b.e')); // undefined
于 2016-03-07T08:20:46.263 回答
0

try您可以使用-包裹可能有害的部分catch

try {
    if (node.data.creatures.humans.women.number === Infinity) {
        // do-someting
    }
} catch () {
    console.log(e);
}

另一种可能更优雅的方法是定义预期的对象结构,并使用例如jQuery.extend()将其与实际数据合并。

var nodeTemplate = {
    data: {
        creatures: {
            humans: {...}
        }
    }
}

这将确保结构符合您的预期,并且不存在的字段具有一些默认值。

然后合并它:

node = $.extend(nodeTemplate, node);
于 2016-03-07T08:20:34.350 回答
0

试图访问一个属性undefined是一个可捕获 TypeError的,所以你可以使用try..catch

try {
    if (node.data.creatures.humans.women.number === Infinity) {
        // do something
    }
} catch (e) {
    // property doesn't exist
}
于 2016-03-07T08:19:06.700 回答