在 JavaScript 中,我们经常会遇到需要判断值是否为空或者是否为假值的场景。为此,JavaScript 提供了两个非常常见的运算符------||(逻辑或运算符)和 ??(空值合并运算符)。虽然它们在某些情况下看起来非常相似,但实际上它们的行为和适用场景却有很大的不同。了解这两者的区别,能帮助我们更好地书写代码,避免一些潜在的错误。
|| 和 ?? 的基本区别
-
||(逻辑或运算符)||是JavaScript中的逻辑运算符,通常用于两个布尔值之间的运算。但是,在实际使用中,||被广泛用于判断一个值是否为假值 ,即判断一个值是否为false、0、NaN、空字符串""、null或undefined,只要是这些值中的任何一个,||就会返回后面的默认值。javascriptlet value = ""; // 空字符串 let result = value || "默认值"; // 返回 "默认值"这就像是你在一家餐厅里,点了一个空盘子(
""),服务员看不下去,直接给你上了默认的美味佳肴------"默认值"。即使你不饿,他也一定要喂你吃。在这个例子中,由于
value是空字符串"",这是一个假值,因此||运算符会返回默认值"默认值"。 -
??(空值合并运算符)??是一种相对较新的运算符,它仅用于判断值是否为null或undefined,如果是其中之一,则返回右侧的默认值;如果不是null或undefined,则返回原值。和||不同,??不会把其他假值(如0、false、空字符串等)视为空值。javascriptlet value = ""; // 空字符串 let result = value ?? "默认值"; // 返回 ""就像你去餐厅点了一个空盘子(
""),但服务员觉得你没事,不会再给你额外的"默认值"。他认为,你没饿到需要"默认值"来救急。在这里,
value是一个空字符串"",而不是null或undefined,所以??不会替换它,result的值仍然是""。
|| 和 ?? 的应用场景
-
使用
||处理假值||用于判断是否为假值 ,并提供一个默认值。当我们需要确保某个变量有一个"有效"的值时,||是一种非常常见的解决方案。javascriptlet userInput = ""; // 用户输入为空字符串 let name = userInput || "默认用户名"; // 返回 "默认用户名"如果
userInput是空字符串"",这时就会使用默认值"默认用户名"。 -
使用
??处理空值如果我们只关心 空值 (
null或undefined),而不希望其他假值(如0、空字符串等)被替换成默认值,那么??是更好的选择。javascriptlet userInput = ""; // 用户输入为空字符串 let name = userInput || "默认用户名"; // 返回 "默认用户名"在这个例子中,
userInput是一个空字符串,它不是null或undefined,所以??运算符不会返回默认值,而是保持原值""。
常见的误区和潜在问题
-
||带来的潜在问题虽然
||运算符可以很方便地处理假值,但是它有时会带来一些意想不到的结果,特别是当我们传递的值本身就是一个有效的假值 (如0或"")时:javascriptlet price = 0; // 商品价格是 0 let discount = price || 100; // 结果会变成 100,而不是 0在上面的例子中,
price为0,这本来是一个有效的价格,但由于0是一个假值,||会将其替换为默认值100,这显然不是我们期望的行为。 -
??也有误用的可能虽然
??更为精确,但它仍然有潜在的误用场景,特别是在我们希望处理所有假值的场景中:javascriptlet userInput = 0; // 用户输入的是 0 let name = userInput ?? "默认用户名"; // 返回 0,而不是 "默认用户名"在这个例子中,
userInput是0,这是一个有效的输入值,不应该用默认值"默认用户名"替换。如果使用??,0将不会被替换,所以name的值就是0,而不是默认的"默认用户名"。
?? 和 || 的性能差异
虽然两者看起来相似,但它们的底层实现不同,可能会对性能产生影响。具体来说:
||运算符:每次遇到一个假值时,它就会继续判断下一个值,直到找到一个真值。??运算符 :仅当左侧的值为null或undefined时才会判断右侧的值。
理论上,?? 的判断条件更严格,因此在某些情况下,使用 ?? 的性能可能会稍好一些。然而,在实际应用中,两者的性能差异微乎其微,通常不需要过多关注。
5.
最佳实践
-
??和||的组合使用有时候,我们可能需要先检查某个值是否为
null或undefined,如果是,再处理其他假值。这时,可以结合??和||来实现更复杂的逻辑:javascriptlet userInput = 0; // 用户输入的是 0 let price = userInput ?? 100 || 200; // 如果 userInput 是 null 或 undefined,返回 100,否则返回 0这里我们先通过
??确保只有在userInput为null或undefined时才替换为100,然后通过||处理假值,确保在0的情况下仍然返回0。 -
使用
??处理空值当我们只关心
null和undefined时,使用??是更合适的选择:javascriptlet foo = null; let bar = foo ?? "默认值"; // 返回 "默认值" -
使用
||处理假值如果我们需要处理所有类型的假值,并提供一个默认值,使用
||是合适的选择:javascriptlet foo = 0; let bar = foo || "默认值"; // 返回 "默认值"
总结
||用于处理任何假值 (包括0、false、空字符串、null和undefined),返回默认值。??仅在值为null或undefined时返回默认值,其他假值不会触发默认值。
在实际开发中,我们需要根据不同的需求来选择使用哪个运算符。如果我们只关心空值(null 和 undefined),就应该使用 ??。而如果我们需要处理其他假值,|| 会是更好的选择。
希望这篇博客能帮助你更好地理解 ?? 和 || 运算符的区别,避免潜在的错误,编写出更加高效和可读的 JavaScript 代码!