在JavaScript中如何访问暂未存在的嵌套对象


Posted in Javascript onJune 18, 2019

前言

JavaScript 是个很神奇的东西。但是 JavaScript中的一些东西确实很奇怪,让人摸不着头脑。其中之一就是当你试图访问嵌套对象时,会遇到这个错误

Cannot read property 'foo' of undefined

在大多数情况下,处理嵌套的对象,通常我们需要安全地访问最内层嵌套的值。 来个粟子:

const user = {
  id: 101,
  email: 'jack@dev.com',
  personalInfo: {
    name: 'Jack',
    address: {
      line1: 'westwish st',
      line2: 'washmasher',
      city: 'wallas',
      state: 'WX'
    }
  }
}

当我们要访问user里面的name及city时,我们会这样写。

const name = user.personalInfo.name;
const userCity = user.personalInfo.address.city;

这是简单而直接的。

但是,由于某种原因,user 中的 personal不可用,对象结构将是这样的:

const user = {
  id: 101,
  email: 'jack@dev.com'
}

现在,如果你在试着访问 name ,将会得到一个 Cannot read property 'name' of undefined 的错误。

const name = user.personalInfo.name; // Cannot read property 'name' of undefined

这是因为我们试图访问对象中不在的 key 为 name 的属性。

大多数开发人员处理这种情况的常用方法如下,

const name = user && user.personalInfo ? user.personalInfo.name : null;

如果你的嵌套结构很简单,这是可以的,但是如果数据嵌套五或六层深,那么你的代码就会看起很混乱:

let city;
if (
  data && data.user && data.user.personalInfo &&
  data.user.personalInfo.addressDetails &&
  data.user.personalInfo.addressDetails.primaryAddress
  ) {
  city = data.user.personalInfo.addressDetails.primaryAddress;
}

有一些技巧可以处理这种混乱的对象结构。

Oliver Steele的嵌套对象访问模式

这是我个人的最爱,因为它使代码看起来干净简单。 我从 stackoverflow 中选择了这种风格,一旦你理解它是如何工作的,它就非常吸引人了。

const name = ((user || {}).personalInfo || {}).name;

使用这种表示法,永远不会遇到无法读取未定义的属性“name”。做法是检查用户是否存在,如果不存在,就创建一个空对象,这样,下一个级别的键将始终从存在的对象访问。

不幸的是,你不能使用此技巧访问嵌套数组。

使用数组Reduce访问嵌套对象

Array reduce 方法非常强大,可用于安全地访问嵌套对象。

const getNestedObject = (nestedObj, pathArr) => {
  return pathArr.reduce((obj, key) =>
    (obj && obj[key] !== 'undefined') ? obj[key] : null, nestedObj);
}

// 将对象结构作为数组元素传入
const name = getNestedObject(user, ['personalInfo', 'name']);

// 要访问嵌套数组,只需将数组索引作为数组元素传入。.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// 这将从 addresses 中的第一层返回 city

Typy

如果你认为上面的方法太过非主流,那么可以使用 Typy库。除了安全访问嵌套对象之外,它还可以做很多很棒的事情。

如果使用Typy,代码将如下所示

import t from 'typy';

const name = t(user, 'personalInfo.name').safeObject;
const city = t(user, 'personalInfo.addresses[0].city').safeObject;
// address is an array

这里还有一些其他的库,如 Lodash 和 Ramda,可以做到这一点。但是在轻量级前端项目中,特别是如果你只需要这些库中的一两个方法时,最好选择另一个轻量级库,或者编写自己的库。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
关于文本框的一些限制控制总结~~
Apr 15 Javascript
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
May 15 Javascript
js 数组的for循环到底应该怎么写?
May 31 Javascript
IE6下出现JavaScript未结束的字符串常量错误的解决方法
Nov 21 Javascript
jQuery 追加元素的方法如append、prepend、before
Jan 16 Javascript
12306验证码破解思路分享
Mar 25 Javascript
layui table 参数设置方法
Aug 14 Javascript
关于微信小程序bug记录与解决方法
Aug 15 Javascript
layui表格数据重载
Jul 27 Javascript
vue-froala-wysiwyg 富文本编辑器功能
Sep 19 Javascript
js 递归json树实现根据子id查父id的方法分析
Nov 08 Javascript
微信小程序的引导页实现代码
Jun 24 Javascript
用Vue.js在浏览器中实现裁剪图像功能
Jun 18 #Javascript
JS删除String里某个字符的方法
Jan 06 #Javascript
简单了解Javscript中兄弟ifream的方法调用
Jun 17 #Javascript
vue中typescript装饰器的使用方法超实用教程
Jun 17 #Javascript
简单学习5种处理Vue.js异常的方法
Jun 17 #Javascript
js/jQuery实现全选效果
Jun 17 #jQuery
解决微信浏览器缓存站点入口文件(IIS部署Vue项目)
Jun 17 #Javascript
You might like
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
微信API接口大全
2015/04/15 PHP
php实现比较两个字符串日期大小的方法
2015/05/12 PHP
示例详解Laravel重置密码代码重构
2016/08/10 PHP
php实现根据身份证获取精准年龄
2020/02/26 PHP
javascript 原型模式实现OOP的再研究
2009/04/09 Javascript
使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)
2011/07/10 Javascript
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
使用AOP改善javascript代码
2015/05/01 Javascript
js实现改进的仿蓝色论坛导航菜单效果代码
2015/09/06 Javascript
JS for...in 遍历语句用法实例分析
2016/08/24 Javascript
如何获取元素的最终background-color
2017/02/06 Javascript
Bootstrap与Angularjs的模态框实例代码
2017/08/03 Javascript
jQuery除指定区域外点击任何地方隐藏DIV功能
2017/11/13 jQuery
js 实现复选框只能选择一项的示例代码
2018/01/23 Javascript
vue实现表格过滤功能
2019/09/27 Javascript
压缩Vue.js打包后的体积方法总结(Vue.js打包后体积过大问题)
2020/02/03 Javascript
nodejs使用socket5进行代理请求的实现
2020/02/21 NodeJs
使用npm命令提示: 'npm' 不是内部或外部命令,也不是可运行的程序的处理方法
2020/05/14 Javascript
element 动态合并表格的步骤
2020/12/31 Javascript
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
基于Python 中函数的 收集参数 机制
2019/12/21 Python
python中使用np.delete()的实例方法
2021/02/01 Python
Tom Dixon官网:英国照明及家具设计和制造公司
2019/03/01 全球购物
be2台湾单身男女交友:全球网路婚姻介绍的领导品牌
2019/10/11 全球购物
速卖通欧盟:Aliexpress EU
2020/08/19 全球购物
资产评估专业学生的自我鉴定
2013/11/14 职场文书
访谈节目策划方案
2014/05/15 职场文书
离婚协议书怎么写2014
2014/09/30 职场文书
房屋转让协议书
2014/10/18 职场文书
思想品德评语大全
2014/12/31 职场文书
2015年植树节活动总结
2015/02/06 职场文书
2015年社区中秋节活动总结
2015/03/23 职场文书
校园安全主题班会
2015/08/12 职场文书
Python获取江苏疫情实时数据及爬虫分析
2021/08/02 Python
css布局巧妙技巧之css三角示例的运用
2022/03/16 HTML / CSS