在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 相关文章推荐
运用Windows XP附带的Msicuu.exe、Msizap.exe来彻底卸载顽固程序
Apr 21 Javascript
jquery中实现简单的tabs插件功能的代码
Mar 02 Javascript
JQuery选择器特辑 详细小结
May 14 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
Aug 15 Javascript
在JavaScript中如何解决用execCommand(
Oct 19 Javascript
JQuery EasyUI学习教程之datagrid 添加、修改、删除操作
Jul 09 Javascript
jQuery实现定位滚动条位置
Aug 05 Javascript
js手机号批量滚动抽奖实现代码
Apr 17 Javascript
JavaScript常见鼠标事件与用法分析
Jan 03 Javascript
详解Vue项目中实现锚点定位
Apr 24 Javascript
小程序扫描普通链接二维码跳转小程序指定界面方法
May 07 Javascript
Vue页面渲染中key的应用实例教程
Jan 12 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中用接口、抽象类、普通基类实现“面向接口编程”与“耦合方法”简述
2011/03/23 PHP
Zend Framework教程之Zend_Db_Table表关联实例详解
2016/03/23 PHP
php单元测试phpunit入门实例教程
2017/11/17 PHP
Javascript实例教程(19) 使用HoTMetal(7)
2006/12/23 Javascript
js中indexof的用法详细解析
2013/12/24 Javascript
html的DOM中document对象forms集合用法实例
2015/01/21 Javascript
cocos2dx骨骼动画Armature源码剖析(一)
2015/09/08 Javascript
Backbone.js框架中简单的View视图编写学习笔记
2016/02/14 Javascript
基于jquery实现智能提示控件intellSeach.js
2016/03/17 Javascript
jquery插件格式实例分析
2016/06/16 Javascript
jQuery animate easing使用方法图文详解
2016/06/17 Javascript
Bootstrap Modal遮罩弹出层(完整版)
2016/11/21 Javascript
xmlplus组件设计系列之列表(4)
2017/04/26 Javascript
js判断传入时间和当前时间大小实例(超简单)
2018/01/11 Javascript
Hexo已经看腻了,来手把手教你使用VuePress搭建个人博客
2018/04/26 Javascript
Vue 中axios配置实例详解
2018/07/27 Javascript
Vue2.5学习笔记之如何在项目中使用和配置Vue
2018/09/26 Javascript
Vue 组件封装 并使用 NPM 发布的教程
2018/09/30 Javascript
vue实现自定义H5视频播放器的方法步骤
2019/07/01 Javascript
利用JS代码自动删除稿件的普通弹幕功能
2019/09/20 Javascript
查找Vue中下标的操作(some和findindex)
2020/08/12 Javascript
JS创建自定义对象的六种方法总结
2020/12/15 Javascript
python重试装饰器示例
2014/02/11 Python
Python绘制的二项分布概率图示例
2018/08/22 Python
在python中利用KNN实现对iris进行分类的方法
2018/12/11 Python
详解Python3 基本数据类型
2019/04/19 Python
django使用admin站点上传图片的实例
2019/07/28 Python
python关闭占用端口方式
2019/12/17 Python
浅谈tensorflow中张量的提取值和赋值
2020/01/19 Python
自我评价范文分享
2014/01/04 职场文书
动员大会主持词
2014/03/20 职场文书
地陪导游欢迎词
2015/01/26 职场文书
孝女彩金观后感
2015/06/10 职场文书
Python生成九宫格图片的示例代码
2021/04/14 Python
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL
mysql字段为NULL索引是否会失效实例详解
2022/05/30 MySQL