2019-10-08 10:46
在 Javascript 中访问某个对象的属性时,经常会碰到 Uncaught TypeError: Cannot read property 'bar' of undefined
错误,例如这样:
let foo
console.log(foo.bar)
该问题之常见,以至于在6个经典的JavaScript报错分析的统计中位列第一。
我最常碰到的情况是 API 返回数据结构变化或值为 null
时,我不得不小心翼翼地处理它们。
在有潜在该问题的地方,一直以来我使用 && 短路写法解决。例如访问如下对象:
let modal = {
visibility: true,
formData: {
name: 'foo',
},
config: {
layout:{
margin: '4px',
},
},
}
console.log(modal.formData && modal.formData.name)
因为 modal
我能确保它是定义过的对象,但 formData
的值可能来自于 API 的返回,所以访问它的下属属性前先判断之,若存在该对象则可访问它的 name
属性,否则就短路在 &&
之前,返回 undefined
而不是报错。
但当对象嵌套多层后这样写就很冗长,比如访问上面对象中的 margin
属性,可能会写成这样:
console.log(modal.config && modal.config.layout && modal.config.layout.margin)
事实上我也这样写了很久,虽然不优雅,但是最安全最保险的方法。
对于大型项目可以使用工具库 Lodash 的 get 方法,安全访问深度嵌套的对象,官方示例如下:
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c');
// => 3
_.get(object, ['a', '0', 'b', 'c']);
// => 3
_.get(object, 'a.b.c', 'default');
// => 'default'
这样就不会有短路写法一长串的 &&
了,最近将本博客中很多短路写法都换成该方法。Ramda.js 中的 path 方法也能实现同样功能。阮一峰更推荐这个库,原因看他的文章《Ramda 函数库参考教程》