代码示例
const payData = payOrder.data?.data?.data ?? payOrder.data?.data ?? payOrder.data ?? payOrder;
一、 可选链 (Optional Chaining) ?.
1. 它解决了什么问题?
在访问嵌套对象的属性时,我们经常会遇到一个经典的错误:Cannot read property 'x' of undefined 或 Cannot read property 'x' of null。
例如,我们想访问 user.profile.address.street,但如果 user.profile 是 undefined,那么 user.profile.address 就会立刻报错。
为了避免这种错误,我们以前不得不这样写:
let street;
if (user && user.profile && user.profile.address) {
street = user.profile.address.street;
}
这种层层的 && 判断非常繁琐。
2. 可选链 ?. 如何工作?
可选链 ?. 允许你安全地访问嵌套对象的属性,而无需检查每个层级是否存在。
它的工作原理很简单:
- 如果
?.前面的部分是null或undefined,那么整个表达式会立即停止执行(“短路”),并返回undefined。 - 如果
?.前面的部分存在(不是null或undefined),那么它会像正常的.一样继续访问下一个属性。
3. 示例
const user = {
profile: {
// address: { street: 'Main St' } // 假设 address 不存在
}
};
// 传统方式,会报错
// const street = user.profile.address.street; // Uncaught TypeError: Cannot read properties of undefined
// 使用可选链,安全访问
const street = user.profile?.address?.street;
console.log(street); // 输出: undefined
// 代码没有报错,而是优雅地返回了 undefined
在你的代码 payOrder.data?.data?.data 中:
payOrder.data:首先访问payOrder的data属性。?.data:如果payOrder.data存在,就继续访问它的data属性;如果payOrder.data是undefined或null,整个表达式直接返回undefined。?.data:再次应用同样的逻辑。
二、 空值合并运算符 (Nullish Coalescing Operator) ??
1. 它解决了什么问题?
我们经常使用 || 来为变量提供一个默认值。
const username = inputUsername || 'Guest';
但 || 有一个问题:它会把所有假值 (falsy values) 都视为 false,包括 0, '' (空字符串), false。
如果 inputUsername 是 0 或空字符串,我们可能希望保留这个值,但 || 会错误地用 'Guest' 覆盖它。
2. 空值合并运算符 ?? 如何工作?
?? 是一个逻辑运算符,当它的左侧操作数是 null 或 undefined 时,它会返回右侧的操作数;否则,返回左侧的操作数。
简单说,它只对 null 和 undefined 这两个 “空值” 起作用。
3. 示例
const defaultName = 'Guest';
// 使用 ||
const name1 = '' || defaultName; // name1 的值是 'Guest' (因为 '' 是 falsy)
const name2 = 0 || 42; // name2 的值是 42 (因为 0 是 falsy)
// 使用 ??
const name3 = '' ?? defaultName; // name3 的值是 '' (因为 '' 不是 null 或 undefined)
const name4 = 0 ?? 42; // name4 的值是 0 (因为 0 不是 null 或 undefined)
const name5 = null ?? defaultName; // name5 的值是 'Guest' (因为左侧是 null)
三、 结合使用:一行代码解决多层嵌套和默认值问题
现在我们来分析你提供的这行代码:const payData = payOrder.data?.data?.data ?? payOrder.data?.data ?? payOrder.data ?? payOrder;
我们可以把它从左到右一步步分解来看:
-
payOrder.data?.data?.data- 尝试获取最深层的
data。 - 如果
payOrder结构是{ data: { data: { data: 'some-value' } } },这部分会返回'some-value'。 - 如果在任何一层
data不存在(是null或undefined),这部分会返回undefined。
- 尝试获取最深层的
-
... ?? payOrder.data?.data??会检查左侧的结果。- 如果第一步返回了
'some-value'(一个真实的值),那么表达式的结果就是'some-value',后续的??都不会再执行。 - 如果第一步返回了
undefined,那么??会继续执行右侧的payOrder.data?.data,尝试获取第二层的data。
-
... ?? payOrder.data- 如果第二步也返回了
undefined,那么继续尝试获取第一层的data。
- 如果第二步也返回了
-
... ?? payOrder- 如果前面所有尝试都失败了(即
payOrder.data本身就是undefined),那么最后就直接使用payOrder对象本身作为payData的值。
- 如果前面所有尝试都失败了(即
总结

182

被折叠的 条评论
为什么被折叠?



