目录
六、提取多个属性(Object Destructuring)
在日常开发中,我们经常会遇到这种情况:后端返回的 JSON 数据结构非常复杂,而我们只想取出某个深度嵌套的字段。
如果直接一层层访问,很容易出现 报错(Cannot read property 'xxx' of undefined) 的问题。本文将介绍几种在 ES6 中常用的写法,帮助你安全高效地获取深层次的属性。
一、常见的深度嵌套对象
例如,后端给我们返回了一个用户信息对象:
const user = {
id: 1,
name: "张三",
profile: {
contact: {
email: "zhangsan@example.com",
phone: "123456789"
},
address: {
city: "合肥",
detail: "XX路 123 号"
}
}
};
假如我们只想获取 email
或者 city
,直接写:
console.log(user.profile.contact.email); // "zhangsan@example.com"
这样没问题,但如果 profile
或 contact
为空,就会报错。
那么该如何优雅、安全地提取呢?
二、传统方式:层层判断
最常见的写法是 短路与运算符 (&&
):
const email = user && user.profile && user.profile.contact && user.profile.contact.email;
console.log(email); // "zhangsan@example.com"
优点:简单直观。
缺点:嵌套层数多的时候,写起来很冗长。
三、ES6 解构赋值(适合已知结构)
如果我们确定某些层级一定存在,可以用 解构赋值:
const { profile: { contact: { email } } } = user;
console.log(email); // "zhangsan@example.com"
但这种写法有个问题:一旦某层级不存在,就会报错。
所以更适合数据结构稳定的场景。
四、可选链(Optional Chaining ?.
)
从 ES2020 开始,JavaScript 引入了 可选链 运算符,可以大大简化写法:
const email = user?.profile?.contact?.email;
const city = user?.profile?.address?.city;
console.log(email); // "zhangsan@example.com"
console.log(city); // "合肥"
如果某一层不存在,不会报错,而是直接返回 undefined
。
这在处理复杂的接口数据时非常好用。
五、配合空值合并运算符(??)
有时候我们希望在属性不存在时,给一个默认值:
const email = user?.profile?.contact?.email ?? "无邮箱";
const city = user?.profile?.address?.city ?? "未知城市";
console.log(email); // "zhangsan@example.com"
console.log(city); // "合肥"
当值为 null
或 undefined
时,才会触发默认值。
六、提取多个属性(Object Destructuring)
如果我们想一次性取出多个嵌套属性,可以这样写:
const email = user?.profile?.contact?.email;
const phone = user?.profile?.contact?.phone;
const city = user?.profile?.address?.city;
console.log({ email, phone, city });
甚至可以封装一个工具函数:
function getNested(obj, path, defaultValue = undefined) {
return path.split('.').reduce((o, key) => (o?.[key]), obj) ?? defaultValue;
}
console.log(getNested(user, "profile.contact.email", "无邮箱"));
console.log(getNested(user, "profile.address.city", "未知城市"));
console.log(getNested(user, "profile.hobby.music", "没有音乐爱好"));
七、总结
在 ES6 以及之后的语法中,提取深度嵌套的对象属性常见方式有:
层层判断 (
&&
) —— 兼容性最好,但代码冗长。解构赋值 —— 简洁,但需要确定层级存在。
可选链运算符 (
?.
) —— 推荐,优雅且安全。配合空值合并运算符 (
??
) —— 可以设置默认值。封装工具函数 —— 适合动态路径或通用需求。
在现代项目中,推荐优先使用 ?.
+ ??
组合,既简洁又安全。