在 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
代码!