如何避免“无法读取未定义的属性”错误?

2022-08-30 02:20:20

在我的代码中,我处理一个数组,该数组具有一些条目,其中许多对象嵌套在彼此内,而有些则没有。它看起来像下面这样:

// where this array is hundreds of entries long, with a mix
// of the two examples given
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];

这给我带来了问题,因为我有时需要遍历数组,而这种不一致会给我带来这样的错误:

for (i=0; i<test.length; i++) {
    // ok on i==0, but 'cannot read property of undefined' on i==1
    console.log(a.b.c);
}

我知道我可以说,但是在彼此嵌套了多达5或6个对象的情况下,这是非常乏味的。有没有其他(更简单的)方法,我可以让它只在它存在的情况下做,但不抛出错误?if(a.b){ console.log(a.b.c)}console.log


答案 1

更新

  • 如果您根据 ECMAScript 2020 或更高版本使用 JavaScript,请参阅可选链接
  • TypeScript 在 3.7 版中添加了对可选链接的支持。
// use it like this
obj?.a?.lot?.of?.properties

ECMASCript 2020 之前的 JavaScript 解决方案或早于 3.7 版的 TypeScript 解决方案:

一个快速的解决方法是将 try/catch 帮助程序函数与 ES6 箭头函数结合使用

function getSafe(fn, defaultVal) {
  try {
    return fn();
  } catch (e) {
    return defaultVal;
  }
}

// use it like this
console.log(getSafe(() => obj.a.lot.of.properties));

// or add an optional default value
console.log(getSafe(() => obj.a.lot.of.properties, 'nothing'));

答案 2

你正在做的事情会引起一个例外(这是理所当然的)。您可以随时执行以下操作:

try{
   window.a.b.c
}catch(e){
   console.log("YO",e)
}

但我不会,而是想想你的用例。

为什么要访问数据,这是您不熟悉的 6 个嵌套级别?什么用例可以证明这一点?

通常,您希望实际验证您正在处理的对象类型。

另外,在旁注中,您不应该使用这样的语句,因为如果a.b为0或即使它是“0”,它也将返回false。而是检查是否if(a.b)a.b !== undefined