在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常用函数 不错
Sep 08 Javascript
JavaScript CSS修改学习第二章 样式
Feb 19 Javascript
jQuery学习笔记之jQuery的动画
Dec 22 Javascript
JQuery性能优化的几点建议
May 14 Javascript
jQuery向后台传入json格式数据的方法
Feb 13 Javascript
浅析JavaScript访问对象属性和方法及区别
Nov 16 Javascript
基于jQuery实现收缩展开功能
Mar 18 Javascript
微信小程序 支付功能开发错误总结
Feb 21 Javascript
webpack2.0配置postcss-loader的方法
Aug 17 Javascript
小试小程序云开发(小结)
Jun 06 Javascript
详解小程序如何改变onLoad的执行时机
Nov 01 Javascript
解决vue初始化项目一直停在downloading template的问题
Nov 09 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
php5新改动之短标记启用方法
2008/09/11 PHP
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
WordPress中获取指定分类及其子分类下的文章数目
2015/12/31 PHP
laravel model 两表联查示例
2019/10/24 PHP
jquery显示和隐藏div特效实例
2013/02/27 Javascript
jQuery中获取checkbox选中项等操作及注意事项
2013/11/24 Javascript
js实现改进的仿蓝色论坛导航菜单效果代码
2015/09/06 Javascript
JavaScript实现的浮动层框架用法实例分析
2015/10/10 Javascript
js实现的简单图片浮动效果完整实例
2016/05/10 Javascript
jQuery实现日期联动效果实例
2016/07/26 Javascript
整理关于Bootstrap导航的慕课笔记
2017/03/29 Javascript
Bootstrap Table使用整理(二)
2017/06/09 Javascript
Bootstrap Table快速完美搭建后台管理系统
2017/09/20 Javascript
使用mock.js随机数据和使用express输出json接口的实现方法
2018/01/07 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
[44:39]2014 DOTA2国际邀请赛中国区预选赛 NE VS CNB
2014/05/21 DOTA
[02:02:38]VG vs Mineski Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
解读Python中degrees()方法的使用
2015/05/18 Python
Python实现合并同一个文件夹下所有txt文件的方法示例
2018/04/26 Python
基于tensorflow加载部分层的方法
2018/07/26 Python
对python实现二维函数高次拟合的示例详解
2018/12/29 Python
python 同时读取多个文件的例子
2019/07/16 Python
TensorFlow实现checkpoint文件转换为pb文件
2020/02/10 Python
keras的三种模型实现与区别说明
2020/07/03 Python
CSS3使用border-radius属性制作圆角
2014/12/22 HTML / CSS
基于HTML5 Canvas:字符串,路径,背景,图片的详解
2013/05/09 HTML / CSS
中邮全球便购:中国邮政速递物流
2017/03/04 全球购物
怎样建立和理解非常复杂的声明?例如定义一个包含N 个指向返回 指向字符的指针的函数的指针的数组?
2013/03/19 面试题
房地产管理毕业生自荐信
2013/11/04 职场文书
公司门卫的岗位职责
2014/02/19 职场文书
简洁的英文求职信范文
2014/05/03 职场文书
小学秋季运动会报道稿
2014/09/30 职场文书
中学教师读书笔记
2015/07/01 职场文书
Nginx安装完成没有生成sbin目录的解决方法
2021/03/31 Servers
Vue + iView实现Excel上传功能的完整代码
2021/06/22 Vue.js
SpringBoot中HttpSessionListener的简单使用方式
2022/03/17 Java/Android