在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 相关文章推荐
js的参数有长度限制吗?发现不能超过2083个字符
Apr 20 Javascript
JavaScript实现找出字符串中第一个不重复的字符
Sep 03 Javascript
javacript使用break内层跳出外层循环分析
Jan 12 Javascript
js中日期的加减法
May 06 Javascript
JavaScript动态添加css样式和script标签
Jul 19 Javascript
AngularJS 中文API参考手册
Jul 28 Javascript
整理关于Bootstrap模态弹出框的慕课笔记
Mar 29 Javascript
详解webpack异步加载业务模块
Jun 23 Javascript
Vue中父组件向子组件通信的方法
Jul 11 Javascript
详解在微信小程序的JS脚本中使用Promise来优化函数处理
Mar 06 Javascript
在微信小程序中使用mqtt服务的方法
Dec 13 Javascript
vue 解决addRoutes多次添加路由重复的操作
Aug 04 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之第五天
2006/10/09 PHP
PHP中error_reporting()函数的用法(修改PHP屏蔽错误)
2011/07/01 PHP
PHP的cURL库简介及使用示例
2015/02/06 PHP
Apache启动报错No space left on device: AH00023该怎么解决
2015/10/16 PHP
php使用PDO获取结果集的方法
2017/02/16 PHP
php中Redis的应用--消息传递
2017/03/28 PHP
thinkphp5 URL和路由的功能详解与实例
2017/12/26 PHP
JS 时间显示效果代码
2009/08/23 Javascript
js最简单的拖拽效果实现代码
2010/09/24 Javascript
js里取容器大小、定位、距离等属性搜集整理
2013/08/19 Javascript
node.js中的emitter.emit方法使用说明
2014/12/10 Javascript
javascript中使用new与不使用实例化对象的区别
2015/06/22 Javascript
IE7浏览器窗口大小改变事件执行多次bug及IE6/IE7/IE8下resize问题
2015/08/21 Javascript
JavaScript实现仿新浪微博大厅和腾讯微博首页滚动特效源码
2015/09/15 Javascript
JavaScript对HTML DOM使用EventListener进行操作
2015/10/21 Javascript
非常实用的12个jquery代码片段
2015/11/02 Javascript
原生js实现日期计算器功能
2017/02/17 Javascript
日期时间范围选择插件:daterangepicker使用总结(必看篇)
2017/09/14 Javascript
jQuery NProgress.js加载进度插件的简单使用方法
2018/01/31 jQuery
vue刷新和tab切换实例
2018/02/11 Javascript
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
2019/05/22 Javascript
JavaScript创建、读取和删除cookie
2019/09/03 Javascript
jquery实现鼠标悬浮弹出气泡提示框
2020/12/23 jQuery
python 装饰器功能以及函数参数使用介绍
2012/01/27 Python
Python 实现文件的全备份和差异备份详解
2016/12/27 Python
将tensorflow的ckpt模型存储为npy的实例
2018/07/09 Python
应用OpenCV和Python进行SIFT算法的实现详解
2019/08/21 Python
python 爬虫如何正确的使用cookie
2020/10/27 Python
纯DOM+CSS3实现简单的小风车动画
2016/09/27 HTML / CSS
实现strstr功能,即在父串中寻找子串首次出现的位置
2016/08/05 面试题
超市国庆节促销方案
2014/02/20 职场文书
人事专员岗位职责说明书
2014/07/30 职场文书
2015年公民道德宣传日活动总结
2015/03/23 职场文书
如何利用python和DOS获取wifi密码
2021/03/31 Python
python中的None与NULL用法说明
2021/05/25 Python
python中的getter与setter你了解吗
2022/03/24 Python