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

新手上路,请多包涵

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

// 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);
}

我知道我可以说 if(a.b){ console.log(a.b.c)} ,但是在最多有 5 或 6 个对象相互嵌套的情况下,这是非常乏味的。有没有其他(更简单的)方法可以让我只在 console.log 存在的情况下执行它,但不会引发错误?

原文由 Ari 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

更新

  • 如果您根据 ECMAScript 2020 或更高版本使用 JavaScript,请参阅 可选链接

  • TypeScript 在 3.7 版本中增加了对可选链的支持。

 // use it like this
 obj?.a?.lot?.of?.properties


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

一个快速的解决方法是使用带有 ES6 箭头函数的 try/catch 辅助函数

 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'));

原文由 str 发布,翻译遵循 CC BY-SA 4.0 许可协议

你正在做的事情引发了一个例外(这是理所当然的)。你总是可以这样做:

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

但我不会,而是考虑您的用例。

为什么要访问您不熟悉的 6 层嵌套数据?什么用例证明了这一点?

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

此外,请注意,您不应使用像 if(a.b) 这样的语句,因为如果 ab 为 0 或即使它为“0”,它也会返回 false。而是检查 a.b !== undefined

原文由 Benjamin Gruenbaum 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题