可选链(Optional Chaining)?. 和 空值合并运算符(Nullish Coalescing Operator)??

代码示例

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;

我们可以把它从左到右一步步分解来看:

  1. payOrder.data?.data?.data

    • 尝试获取最深层的 data
    • 如果 payOrder 结构是 { data: { data: { data: 'some-value' } } },这部分会返回 'some-value'
    • 如果在任何一层 data 不存在(是 null 或 undefined),这部分会返回 undefined
  2. ... ?? payOrder.data?.data

    • ?? 会检查左侧的结果。
    • 如果第一步返回了 'some-value' (一个真实的值),那么表达式的结果就是 'some-value',后续的 ?? 都不会再执行。
    • 如果第一步返回了 undefined,那么 ?? 会继续执行右侧的 payOrder.data?.data,尝试获取第二层的 data
  3. ... ?? payOrder.data

    • 如果第二步也返回了 undefined,那么继续尝试获取第一层的 data
  4. ... ?? payOrder

    • 如果前面所有尝试都失败了(即 payOrder.data 本身就是 undefined),那么最后就直接使用 payOrder 对象本身作为 payData 的值。

总结

 

 

在许多编程语言中,尤其是支持可选链Optional Chaining空值合并运算符Nullish Coalescing Operator)的语言(如 JavaScript、TypeScript 等),`defaultLocal.default?.message ?? {}` 这种语法有特定的含义。 ### 语法拆分解释 #### 1. `defaultLocal` 这是一个变量名,代表一个对象。这个对象可能包含多个属性,其中一个可能是 `default` 属性。 #### 2. `defaultLocal.default` 尝试访问 `defaultLocal` 对象的 `default` 属性。但 `defaultLocal` 可能为 `null` 或者 `undefined`,直接访问可能会导致运行时错误。 #### 3. `defaultLocal.default?.` 这里使用了可选链操作符 `?.`。可选链操作符允许在访问对象属性时,如果对象为 `null` 或者 `undefined`,则不会抛出错误,而是直接返回 `undefined`。也就是说,如果 `defaultLocal` 为 `null` 或 `undefined`,那么 `defaultLocal.default` 会直接返回 `undefined`,而不会报错。 #### 4. `defaultLocal.default?.message` 使用可选链操作符继续尝试访问 `defaultLocal.default` 对象的 `message` 属性。如果 `defaultLocal` 或者 `defaultLocal.default` 为 `null` 或 `undefined`,则整个表达式 `defaultLocal.default?.message` 会返回 `undefined`。 #### 5. `?? {}` 这里使用了空值合并运算符 `??`。空值合并运算符用于在左侧表达式为 `null` 或 `undefined` 时,返回右侧的值。所以,如果 `defaultLocal.default?.message` 的结果是 `null` 或 `undefined`,则整个表达式 `defaultLocal.default?.message ?? {}` 会返回一个空对象 `{}`。 ### 代码示例 ```typescript // 示例数据 const defaultLocal = { default: { message: { hello: 'world' } } }; // 使用可选链空值合并运算符 const result = defaultLocal.default?.message ?? {}; console.log(result); // 输出: { hello: 'world' } // 当 defaultLocal 为 null 时 const nullDefaultLocal = null; const nullResult = nullDefaultLocal.default?.message ?? {}; console.log(nullResult); // 输出: {} ``` ### 总结 `defaultLocal.default?.message ?? {}` 这个表达式的含义是:尝试访问 `defaultLocal` 对象的 `default` 属性中的 `message` 属性,如果在访问过程中遇到 `null` 或 `undefined`,则返回一个空对象 `{}`。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值