可选链操作符(?.
)和空值合并操作符(??
)是一对绝佳搭档,经常一起使用。可选链用于安全访问嵌套属性,而空值合并用于在属性为null
或undefined
时提供默认值,两者结合可以优雅地处理可能缺失的数据。
以下是它们一起使用的常见示例:
// 示例数据:可能不完整的用户信息
const user = {
name: "张三",
address: {
city: "北京",
// street 可能不存在
},
contact: {
phone: null, // 明确值,但明确存在
// email 可能不存在
},
// 可能没有hobby属性
};
// 1. 获取可能缺失的属性,并设置默认值
const street = user?.address?.street ?? "未知街道";
const email = user?.contact?.email ?? "未提供邮箱";
const hobby = user?.hobby ?? "无爱好";
console.log(street); // "未知街道"(因为street不存在)
console.log(email); // "未提供邮箱"(因为email不存在)
console.log(hobby); // "无爱好"(因为hobby属性不存在)
// 2. 处理数组场景
const data = {
items: [
{ id: 1, name: "商品1" },
// 可能只有更少的元素
]
// items 可能为null
};
const secondItemName = data?.items?.[1]?.name ?? "第二个商品不存在";
console.log(secondItemName); // "第二个商品不存在"(因为数组只有一个元素)
// 3. 处理函数场景
const utils = {
format: (value) => `格式化: ${value}`,
// 可能没有parse函数
};
const parsedValue = utils.parse?.("123") ?? "解析失败";
console.log(parsedValue); // "解析失败"(因为parse函数不存在)
// 4. 注意:空值合并只对null/undefined生效,对空字符串、0等falsy值不生效
const score = {
value: 0, // 0是有效的值
comment: "" // 空字符串是有效的值
};
const finalScore = score?.value ?? 60; // 0(不会使用默认值60)
const finalComment = score?.comment ?? "无评价"; // ""(不会使用默认值)
console.log(finalScore); // 0
console.log(finalComment); // ""
关键区别说明:
- 可选链(
?.
):当访问的属性不存在(null
或undefined
)时,会短路返回undefined
,避免报错 - 空值合并(
??
):仅当左侧是null
或undefined
时,才返回右侧的默认值 - 两者结合:先安全访问属性,再为可能的空值提供默认值,比传统的
||
判断更精确(||
会把0、空字符串等视为假值)
这种组合在处理API返回数据、配置对象等场景中非常实用,能大幅简化代码并减少错误。