在 JavaScript 中处理空值(null、undefined)
前言:如果想安全访问对象的嵌套属性或调用函数以及处理可能为 null 或 undefined 的值,我们可以使用 逻辑与&& 和 逻辑或|| 来处理。虽然有效,但这些方法的主要用途是进行逻辑判断,而不是空值处理。所以在ES2020引入了可选链(?.)、空值合并(??),它们很好地解决了以前方法引起的一些问题。
一、假值和空值
首先我们需要了解假值和空值的概念:
-
假值:在 JavaScript 中,以下值会被当作
false处理:false、null、undefined、0、-0、NaN、""(空字符串) -
空值:仅指
null和undefined
二、安全访问
当我们想要访问对象的嵌套属性或调用函数时,可能会遇到某个对象属性或调用者为null 或 undefined的情况,而我们又不想让其报错导致终止程序,这时就可以使用以下两种方法来检查访问或调用的过程,它们允许在遇到这种情况时避免抛出错误。
1. 使用逻辑与运算符 (&&)
假设我们有一个用户对象 user,其中包含地址信息 address,而地址信息中又包含城市信息 city:
// 创建一个user对象
const user = {
address: {
city: "Beijing"
}
};
如果此时我们直接访问user.address.city,那么这是安全的。但如果 user.address 不存在,则会抛出错误。在早期,我们通常使用逻辑与运算符来避免这种情况:
console.log(user.address && user.address.city); // 输出 "Beijing"
console.log(user.unknown && user.unknown.city); // 输出 undefined
但是对于更深层次的嵌套属性,需要进行多层检查以确保每一层都不是 null 或 undefined,使用&&就会有些繁琐:
// 假定有个obj对象其中嵌套了3个对象
const value = obj && obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
如上,这种方法虽然可用,但代码会变得冗长、难以阅读,并且容易出错。同时每次添加或修改属性层级时都需要调整代码。
2. 使用可选链操作符(?.)
?. 是专门用于 “安全访问” 的,它极大地简化了这种检查过程,避免了报错:
// 创建一个user对象
const user = {
address: {
city: "Beijing"
}
};
console.log(user?.address?.city); // "Beijing"
console.log(user?.unknown?.city); // "undefined"
console.log(user?.address?.phone); // "undefined"
显而易见,?. 的工作过程就像正常访问一样,不过只要中间的某个节点为空值,那么表达式就会返回undefined,而不是抛出错误。
同时即便访问不存在的属性,也不会报错,仍然返回undefined,极大地提高了代码的健壮性。
小总结:
&&是通过逻辑判断实现的,所以只要运算符的左侧为假值,都会短路并返回该假值,否则返回右侧值;?.是专门实现安全访问的,所以只要访问的过程中出现空值,都会短路并返回undefined,否则返回右侧值;
三、空值处理(提供默认值)
当一个变量可能是 null 或 undefined 时,我们可以使用以下两种方法为其提供默认值。
1. 使用逻辑或运算符 (||)
在以往,我们使用 || 会有些意外的结果:
假设我们提供数据 data.name ,我们希望在它为空值时使用一个默认名字。
const data = {
name:null
}
console.log(data.name || "Lihua") // "Lihua"
但是要注意,这种方式不仅会在 null 和 undefined 时返回默认值,也会在 false, 0, '' (空字符串) 等其他假值情况下返回默认值 ,这可能不是你想要的行为。
2. 使用空值合并操作符(??)
空值合并操作符仅在左侧的操作数为 null 或 undefined 时返回右侧的默认值,否则返回左侧的操作数。这使得我们可以优雅地处理缺失数据的情况。
console.log(null ?? "default"); // 输出 "default"
console.log(undefined ?? "default"); // 输出 "default"
console.log("Hello" ?? "default"); // 输出 "Hello"
console.log("" ?? "default"); // 输出 ""
小总结:
||是通过逻辑判断实现的,所以只要运算符的左侧为假值,就会返回右侧默认值;??是专门实现空值处理的,所以只要操作符的左侧为空值,就会返回右侧默认值;
四、大总结
?.:安全访问,只认null/undefined??:空值默认,只认null/undefined&&:逻辑与,认所有假值,适合条件判断||:逻辑或,认所有假值,适合 “任一为真” 的判断
更多推荐

所有评论(0)