以超酷的方式安全地访问JavaScript中的嵌套对象
JavaScript是惊人的,我们都知道。但是JavaScript中的一些东西真的很奇怪,它们让我们大开眼界。其中一个问题是当您尝试访问嵌套对象时与此错误的对抗,
无法读取未定义的属性'foo'
大多数情况下,当我们使用JavaScript时,我们将处理嵌套对象,并且通常我们需要安全地访问最里面的嵌套值。
我们以此嵌套对象为例。
const user = { id: 101, email: 'jack@dev.com', personalInfo: { name: 'Jack', address: { line1: 'westwish st', line2: 'washmasher', city: 'wallas', state: 'WX' } }}
要访问我们用户的名字,我们会写
const name = user.personalInfo.name;const userCity = user.personalInfo.address.city;
这很简单直接。
但是,由于某种原因,如果我们用户的个人信息不可用,那么对象结构将是这样的。
const user = { id: 101, email: 'jack@dev.com'}
现在,如果您尝试访问该名称,您将被抛出 无法读取未定义的属性“名称”。
const name = user.personalInfo.name; // Cannot read property 'name' of undefined
这是因为我们试图name 从不存在的对象访问 密钥。
大多数开发人员处理这种情况的常用方法是
const name = user && user.personalInfo ? user.personalInfo.name : null;// undefined error will NOT be thrown as we check for existence before access如果您的嵌套结构很简单,这是可以的,但是如果您的数据嵌套了5或6级,那么您的代码看起来会非常混乱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;
使用这种表示法,您将永远不会遇到 无法读取未定义的属性“名称”。你基本上检查用户是否存在,如果没有,你动态创建一个空对象。这样,下一级键将 始终从存在的对象或空对象访问,但永远不会从未定义。
不幸的是, 您无法使用此技巧访问嵌套数组
使用Array Reduce访问嵌套对象
Array reduce方法非常强大,可用于安全地访问嵌套对象。
const getNestedObject = (nestedObj, pathArr) => { return pathArr.reduce((obj, key) => (obj && obj[key] !== 'undefined') ? obj[key] : null, nestedObj);}// pass in your object structure as array elementsconst name = getNestedObject(user, ['personalInfo', 'name']);// to access nested array, just pass in array index as an element the path array.const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);// this will return the city from the first address item.
Typy
https://github.com/flexdinesh/typy
如果您认为上述方法过于主流,那么您应该尝试 我编写的Typy库。除了安全地访问嵌套对象之外,它还有许多令人敬畏的东西。
它以npm包的形式提供 - 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这样的其他库可以做到这一点。但是在轻量级的前端项目中,特别是如果你只需要这些库中的一两种方法,最好选择替代轻量级的lib,或者更好,自己编写。
快乐'安全地访问JavaScript中的嵌套对象'!
链接:https://javascriptkicks.com/articles/236734/accessing-nested-objects-in-javascript