各位观众老爷们,大家好!今天咱们来聊聊JavaScript里两个能让代码更优雅、更健壮的小可爱:可选链式调用(Optional Chaining)和空值合并运算符(Nullish Coalescing)。这俩货就像代码界的润滑剂,能有效避免“Uncaught TypeError: Cannot read property of undefined/null”这种让人头疼的错误,让你的代码在面对不确定数据时也能稳如泰山。
一、Optional Chaining (?.):再也不怕“点”到空了!
在JavaScript中,我们经常需要访问嵌套对象的属性,比如 user.profile.address.city
。但问题来了,如果 user
、profile
或者 address
中间任何一个环节是 null
或 undefined
,就会抛出一个错误,程序就直接嗝屁了。以前我们为了避免这种情况,只能用一堆 &&
来判断:
let city;
if (user && user.profile && user.profile.address) {
city = user.profile.address.city;
} else {
city = undefined; // 或者其他默认值
}
console.log(city); // 输出 undefined,避免了错误
这段代码虽然能避免错误,但是看起来又臭又长,可读性极差。而且,每多一层嵌套,就要多写一个 &&
,简直让人崩溃!
Optional Chaining 就是来拯救我们的。它允许你安全地访问嵌套对象的属性,即使中间某个属性不存在,也不会报错,而是直接返回 undefined
。 语法很简单,就是在属性访问的点号 .
前面加上一个问号 ?
。
const city = user?.profile?.address?.city;
console.log(city); // 输出 undefined,如果 user, profile 或 address 为 null/undefined
是不是简洁多了??.
就像一个“空值保险”,只要遇到 null
或 undefined
,就直接短路,返回 undefined
,后面的属性访问就直接跳过了。
Optional Chaining 的使用场景:
- 访问可能不存在的属性: 这是最常见的用途,可以避免
TypeError
。 - 调用可能不存在的方法: 也可以用在方法调用上,比如
user?.profile?.getAddress?.()
。如果getAddress
不是一个函数,或者profile
为null
或undefined
,也不会报错,而是返回undefined
。 - 数组访问: 虽然不常见,但也可以用于数组,比如
arr?.[index]
。
Optional Chaining 的注意事项:
?.
只能用于属性访问和方法调用,不能用于变量名本身。?.
只能在null
或undefined
时短路,对于其他 falsy 值(比如0
、''
、false
),不会起作用。
举个例子:
假设我们有一个用户对象,但用户信息可能不完整:
const user1 = {
name: "Alice",
profile: {
address: {
city: "New York"
}
}
};
const user2 = {
name: "Bob"
};
console.log(user1?.profile?.address?.city); // 输出 "New York"
console.log(user2?.profile?.address?.city); // 输出 undefined,不会报错
再来一个方法调用的例子:
const obj1 = {
myMethod: () => {
console.log("Method called!");
}
};
const obj2 = {};
obj1.myMethod?.(); // 输出 "Method called!"
obj2.myMethod?.(); // 不会报错,也不会输出任何东西
如果没有 ?.
,obj2.myMethod()
就会报错,因为 obj2.myMethod
是 undefined
。
表格总结 Optional Chaining:
运算符 | 作用 | 返回值 |
---|---|---|
?. |
安全地访问对象的属性或调用方法,如果链中的任何一个值为 null 或 undefined |
如果链中的任何一个值为 null 或 undefined ,则返回 undefined ,否则返回属性值或方法调用的结果 |
二、Nullish Coalescing (??):终于可以区分 null/undefined
和 0/''/false
了!
Nullish Coalescing 运算符 ??
提供了一种简洁的方式来为变量设置默认值,但它只在变量的值为 null
或 undefined
时才生效。这与 ||
运算符不同,||
会将任何 falsy 值(0
、''
、false
、null
、undefined
)都视为“空”,并使用默认值。
||
运算符的问题:
const count = 0;
const displayName = count || "Guest";
console.log(displayName); // 输出 "Guest",因为 0 是一个 falsy 值
在这个例子中,我们希望 displayName
默认为 "Guest",但如果 count
是 0,||
运算符会错误地将其视为“空”,并使用默认值。这显然不是我们想要的。
??
运算符的优势:
??
运算符只在变量的值为 null
或 undefined
时才使用默认值。对于其他 falsy 值,它会保留变量的原始值。
const count = 0;
const displayName = count ?? "Guest";
console.log(displayName); // 输出 0,因为 count 不是 null 或 undefined
现在,displayName
正确地输出了 0,因为 ??
运算符只关心 null
和 undefined
。
??
运算符的使用场景:
- 为变量提供默认值,但只在变量为
null
或undefined
时生效。 - 区分
null/undefined
和其他 falsy 值。
举个例子:
const name = null;
const age = 0;
const message = "";
const defaultName = name ?? "Unknown";
const defaultAge = age ?? 25;
const defaultMessage = message ?? "No message";
console.log(defaultName); // 输出 "Unknown"
console.log(defaultAge); // 输出 0
console.log(defaultMessage); // 输出 ""
??
运算符的注意事项:
-
??
运算符不能与||
运算符直接连用,否则会抛出一个语法错误。你需要用括号来明确优先级。// 错误的写法: // const value = null ?? "default" || "anotherDefault"; // SyntaxError: Unexpected token '||' // 正确的写法: const value = (null ?? "default") || "anotherDefault"; // 输出 "default" const value2 = null ?? ("default" || "anotherDefault"); // 输出 "default"
-
??
运算符的优先级低于&&
和||
运算符。
表格总结 Nullish Coalescing:
运算符 | 作用 | 返回值 |
---|---|---|
?? |
为变量提供默认值,但只在变量的值为 null 或 undefined 时生效 |
如果变量的值不是 null 或 undefined ,则返回变量的值,否则返回默认值 |
三、Optional Chaining 和 Nullish Coalescing 的组合使用:让代码更上一层楼!
这两个运算符可以一起使用,让你的代码更加简洁、健壮。
例子:
假设我们有一个用户对象,但用户信息可能不完整,并且我们希望为用户的城市设置一个默认值:
const user1 = {
name: "Alice",
profile: {
address: {
city: "New York"
}
}
};
const user2 = {
name: "Bob"
};
const city1 = user1?.profile?.address?.city ?? "Unknown City";
const city2 = user2?.profile?.address?.city ?? "Unknown City";
console.log(city1); // 输出 "New York"
console.log(city2); // 输出 "Unknown City"
在这个例子中,我们首先使用 Optional Chaining 安全地访问用户的城市信息,如果任何一个环节是 null
或 undefined
,?.
运算符会返回 undefined
。然后,我们使用 Nullish Coalescing 运算符 ??
为城市设置一个默认值 "Unknown City"。
四、实际应用场景:
-
处理 API 返回的数据:
API 返回的数据结构可能不固定,某些字段可能不存在。使用 Optional Chaining 和 Nullish Coalescing 可以安全地访问数据,并为缺失的字段提供默认值。
async function fetchData() { const response = await fetch('https://api.example.com/data'); const data = await response.json(); const userName = data?.user?.name ?? "Guest"; const userCity = data?.user?.profile?.address?.city ?? "Unknown"; console.log(`User: ${userName}, City: ${userCity}`); }
-
处理用户配置:
用户可以自定义配置,但某些配置项可能没有设置。使用 Optional Chaining 和 Nullish Coalescing 可以安全地访问配置项,并为缺失的配置项提供默认值。
const userConfig = { theme: "dark" // 没有设置 font size }; const theme = userConfig.theme ?? "light"; const fontSize = userConfig.fontSize ?? 16; console.log(`Theme: ${theme}, Font Size: ${fontSize}`); // 输出 Theme: dark, Font Size: 16
-
处理表单数据:
表单中的某些字段可能为空。使用 Optional Chaining 和 Nullish Coalescing 可以安全地访问表单数据,并为缺失的字段提供默认值。
<input type="text" id="name" name="name"> <input type="number" id="age" name="age">
const form = document.querySelector('form'); form.addEventListener('submit', (event) => { event.preventDefault(); const name = form.elements.name.value || "Anonymous"; // 旧方法,使用 || const age = form.elements.age.value ?? 0; // 使用 ?? console.log(`Name: ${name}, Age: ${age}`); });
五、总结:
Optional Chaining (?.
) 和 Nullish Coalescing (??
) 是 JavaScript 中非常有用的两个运算符,它们可以帮助你编写更简洁、更健壮的代码。
?.
运算符可以安全地访问嵌套对象的属性,避免TypeError
。??
运算符可以为变量提供默认值,但只在变量的值为null
或undefined
时生效。
合理地使用这两个运算符,可以大大提高代码的可读性和可维护性,减少 bug 的数量,让你在开发过程中更加得心应手。
记住,代码就像盖房子,地基要打牢,细节要做好。Optional Chaining 和 Nullish Coalescing 就是帮你打牢地基,处理好细节的利器。掌握了它们,你的代码就能经得起各种风吹雨打,稳如磐石!
今天的分享就到这里,希望大家有所收获。如果有什么问题,欢迎随时提问! 谢谢大家!