在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 相关文章推荐
ie 调试javascript的工具
Apr 29 Javascript
基于jquery的商品展示放大镜
Aug 07 Javascript
最短的javascript:地址栏载入脚本代码
Oct 13 Javascript
jQuery多个input求和的实现方法
Feb 12 Javascript
浅谈javascript 函数表达式和函数声明的区别
Jan 05 Javascript
【经典源码收藏】jQuery实用代码片段(筛选,搜索,样式,清除默认值,多选等)
Jun 07 Javascript
JS中关于事件处理函数名后面是否带括号的问题
Nov 16 Javascript
JS简单实现表格排序功能示例
Dec 20 Javascript
jQuery实现动态给table赋值的方法示例
Jul 04 jQuery
js和jQuery以及easyui实现对下拉框的指定赋值方法
Jan 23 jQuery
javascript中的隐式调用
Feb 10 Javascript
jquery实现自定义树形表格的方法【自定义树形结构table】
Jul 12 jQuery
用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
咖啡豆的最常见发酵处理方法,详细了解一下
2021/03/03 冲泡冲煮
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
PHP中spl_autoload_register函数的用法总结
2013/11/07 PHP
Linux中用PHP判断程序运行状态的2个方法
2014/05/04 PHP
destoon数据库表说明汇总
2014/07/15 PHP
微信获取用户地理位置信息的原理与步骤
2015/11/12 PHP
在PHP 7下安装Swoole与Yar,Yaf的方法教程
2017/06/02 PHP
javascript语句中的CDATA标签的意义
2007/05/09 Javascript
JavaScript 核心参考教程 内置对象
2009/10/13 Javascript
jquery插件之信息弹出框showInfoDialog(成功/错误/警告/通知/背景遮罩)
2013/01/09 Javascript
JQuery 中几个类选择器的简单使用介绍
2013/03/14 Javascript
jquery中map函数与each函数的区别实例介绍
2014/06/23 Javascript
js利用正则表达式检验输入内容是否为网址
2016/07/05 Javascript
Vue.js之slot深度复制详解
2017/03/10 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
2017/04/21 jQuery
vue下跨域设置的相关介绍
2017/08/26 Javascript
seajs模块压缩问题与解决方法实例分析
2017/10/10 Javascript
Three.js基础学习教程
2017/11/16 Javascript
vue-cli3.0 脚手架搭建项目的过程详解
2018/10/19 Javascript
原生js实现的金山打字小游戏(实例代码详解)
2020/03/16 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
2020/05/19 jQuery
python 垃圾收集机制的实例详解
2017/08/20 Python
python用户评论标签匹配的解决方法
2018/05/31 Python
解决python文件双击运行秒退的问题
2019/06/24 Python
python中pygame安装过程(超级详细)
2019/08/04 Python
Python搭建代理IP池实现接口设置与整体调度
2019/10/27 Python
关于python pycharm中输出的内容不全的解决办法
2020/01/10 Python
Python开发企业微信机器人每天定时发消息实例
2020/03/17 Python
CSS3等相关属性制作分页导航实现代码
2012/12/24 HTML / CSS
html5 input输入实时检测以及延时优化
2018/07/18 HTML / CSS
财务主管的岗位职责
2013/12/30 职场文书
法学毕业生自我鉴定
2014/01/31 职场文书
安全大检查实施方案
2014/02/22 职场文书
关于实现中国梦的心得体会
2016/01/05 职场文书
Java 将PPT幻灯片转为HTML文件的实现思路
2021/06/11 Java/Android
CSS3实现指纹特效代码
2022/03/17 HTML / CSS