在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 相关文章推荐
xml文档转换工具,附图表例子(hta)
Nov 17 Javascript
在jQuery1.5中使用deferred对象 着放大镜看Promise
Mar 12 Javascript
左侧是表头的JS表格控件(自写,网上没有的)
Jun 04 Javascript
js 上下左右键控制焦点(示例代码)
Dec 14 Javascript
浅谈js中的in-for循环
Jun 28 Javascript
JS查找字符串中出现次数最多的字符
Sep 05 Javascript
JS 仿支付宝input文本输入框放大组件的实例
Nov 14 Javascript
基于vue.js无缝滚动效果
Jan 25 Javascript
vue表单验证你真的会了吗?vue表单验证(form)validate
Apr 07 Javascript
Vue 实现前进刷新后退不刷新的效果
Jun 14 Javascript
jquery实现垂直手风琴菜单
Mar 04 jQuery
vue中div禁止点击事件的实现
Apr 02 Vue.js
用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生成zip压缩文件的方法详解
2013/06/09 PHP
php将access数据库转换到mysql数据库的方法
2014/12/24 PHP
php上传文件并显示上传进度的方法
2015/03/24 PHP
PHP实现连接设备、通讯和发送命令的方法
2015/10/13 PHP
PHP数组游标实现对数组的各种操作详解
2016/01/26 PHP
YII框架模块化处理操作示例
2019/04/26 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
2019/07/24 PHP
thinkphp3.2框架中where条件查询用法总结
2019/08/13 PHP
JavaScript 学习笔记二 字符串拼接
2010/03/28 Javascript
JavaScript下通过的XMLHttpRequest发送请求的代码
2011/06/28 Javascript
THREE.JS入门教程(4)创建粒子系统
2013/01/24 Javascript
js对列表中第一个值处理与jsp页面对列表中第一个值处理的区别详解
2013/11/05 Javascript
仿Angular Bootstrap TimePicker创建分钟数-秒数的输入控件
2016/07/01 Javascript
Angular的模块化(代码分享)
2016/12/26 Javascript
最常用的jQuery表单验证(简单)
2017/05/23 jQuery
nodejs连接mysql数据库及基本知识点详解
2018/03/20 NodeJs
详解Ubuntu安装angular-cli遇到的坑
2018/09/08 Javascript
使用Angular自定义字段校验指令的方法示例
2019/02/01 Javascript
js实现搜索提示框效果
2020/09/05 Javascript
在windows下快速搭建web.py开发框架方法
2016/04/22 Python
Python实现拷贝多个文件到同一目录的方法
2016/09/19 Python
Python使用sftp实现上传和下载功能(实例代码)
2017/03/14 Python
Python 异常处理的实例详解
2017/09/11 Python
Python3 实现随机生成一组不重复数并按行写入文件
2018/04/09 Python
python实现生成Word、docx文件的方法分析
2019/08/30 Python
python3 assert 断言的使用详解 (区别于python2)
2019/11/27 Python
Python通过VGG16模型实现图像风格转换操作详解
2020/01/16 Python
Hotter Shoes美国官网:英国最受欢迎的舒适鞋
2018/08/02 全球购物
C#中有没有静态构造函数,如果有是做什么用的?
2016/06/04 面试题
选秀节目策划方案
2014/06/06 职场文书
音乐学专业求职信
2014/07/22 职场文书
检讨书范文300字
2015/01/28 职场文书
2015年学校安全工作总结
2015/04/22 职场文书
go xorm框架的使用
2021/05/22 Golang
PyTorch dropout设置训练和测试模式的实现
2021/05/27 Python
MySQL笔记 —SQL运算符
2022/01/18 MySQL