资讯专栏INFORMATION COLUMN

如何在JavaScript中访问暂未存在的嵌套对象

malakashi / 2191人阅读

摘要:做法是检查用户是否存在,如果不存在,就创建一个空对象,这样,下一个级别的键将始终从存在的对象访问。使用数组访问嵌套对象方法非常强大,可用于安全地访问嵌套对象。除了安全访问嵌套对象之外,它还可以做很多很棒的事情。

想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!

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里面的namecity时,我们会这样写。

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

这里还有一些其他的库,如 LodashRamda,可以做到这一点。但是在轻量级前端项目中,特别是如果你只需要这些库中的一两个方法时,最好选择另一个轻量级库,或者编写自己的库。

交流

干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。

https://github.com/qq44924588...

我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,即可看到福利,你懂的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104785.html

相关文章

  • JavaScript 进阶 从实现理解闭包(校对版)

    摘要:嵌套函数在一个函数中创建另一个函数,称为嵌套。这在很容易实现嵌套函数可以访问外部变量,帮助我们很方便地返回组合后的全名。更有趣的是,嵌套函数可以作为一个新对象的属性或者自己本身被。 来源于 现代JavaScript教程闭包章节中文翻译计划本文很清晰地解释了闭包是什么,以及闭包如何产生,相信你看完也会有所收获 关键字Closure 闭包Lexical Environment 词法环境En...

    wuyangnju 评论0 收藏0
  • javascript安全地访问深层嵌套

    摘要:介绍这是一篇短文,旨在展示多种在中安全地访问深层嵌套值的方式。所以每次我们想要访问深度嵌套的数据时,都必须明确地进行手动检查。我们还触及了,可以更新深度嵌套数据而不会改变对象。 介绍 这是一篇短文,旨在展示多种在javascript中安全地访问深层嵌套值的方式。下面的例子通过不同的方式来解决这一问题。 开始之前,让我们看下实际遇到这种状况时.. 假设有一个props对象(如下),当我们...

    zacklee 评论0 收藏0
  • 使用leancloud给简历加数据库,实现留言功能

    摘要:拥有登录注册手机验证码功能收费存储任意信息读取任意信息搜索任意信息删除任意信息更新任意信息等功能。 使用leancloud给简历加数据库,实现留言功能 这篇博客的源代码是我的正在写的在线简历完整代码(项目暂未完成)预览地址 在本地预览项目的时候用的http-server 前端的两大块: 操纵DOM:DOM API/jQuery Ajax:http请求和响应/XMLHttpReques...

    susheng 评论0 收藏0
  • 理解JavaScript核心知识点:作用域

    摘要:也毫不例外,但在中作用域的特性与其他高级语言稍有不同,这是很多学习者久久难以理清的一个核心知识点。主要使用的是函数作用域。 关于作用域:About Scope 作用域是程序设计里的基础特性,是作用域使得程序运行时可以使用变量存储值、记录和改变程序的状态。JavaScript 也毫不例外,但在 JavaScript 中作用域的特性与其他高级语言稍有不同,这是很多学习者久久难以理清的一个核...

    HelKyle 评论0 收藏0
  • 【8】JavaScript 函数高级——闭包

    摘要:理解二包含被引用变量函数的对象极少数人。在函数外部能直接访问函数内部的局部变量吗不能但我们可以通过闭包让外部操作它。死亡在嵌套的内部函数成为垃圾对象时。 JavaScript函数高级——闭包 一、引子实例 00_引入 测试1 测试2 测试3 var btns = document.getElementsByTagName(butto...

    Lorry_Lu 评论0 收藏0

发表评论

0条评论

malakashi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<