与Is there a "null coalescing" operator in JavaScript?相关- JavaScript现在有一个??
运算符,我看到它使用得更频繁。以前大多数JavaScript代码使用||
。
let userAge = null
// These values will be the same.
let age1 = userAge || 21
let age2 = userAge ?? 21
在什么情况下??
和||
会有不同的行为?
与Is there a "null coalescing" operator in JavaScript?相关- JavaScript现在有一个??
运算符,我看到它使用得更频繁。以前大多数JavaScript代码使用||
。
let userAge = null
// These values will be the same.
let age1 = userAge || 21
let age2 = userAge ?? 21
在什么情况下??
和||
会有不同的行为?
8条答案
按热度按时间pdsfdshx1#
如果left是falsy,则OR运算符
||
使用右值,而如果left是null
或undefined
,则空合并运算符??
使用右值。这些运算符通常用于在缺少第一个运算符时提供默认值。
但是,如果左值可能包含
""
或0
或false
(因为这些是falsy values),OR运算符||
可能会有问题:在许多情况下,如果left是
null
或undefined
,则可能只需要right值。这就是nullish合并运算符??
的作用:虽然
??
运算符在current LTS versions of Node(v10和v12)中不可用,但您可以将其用于某些版本的TypeScript或Node:??
运算符于2019年11月添加到TypeScript 3.7中。最近,
??
运算符是included in ES2020,它由Node 14(于2020年4月发布)支持。**当支持空合并运算符
??
时,我通常使用它而不是OR运算符||
(除非有很好的理由不这样做)。jm2pwxwz2#
总之
Nullish Coalescing Operator
??
区分:null
,undefined
)false
、0
、''
等)||
(逻辑OR)对这两种情况的处理是相同的。我创建了一个简单的图形来说明JavaScript中 nullish 和 falsey 值的关系:
进一步说明:
如上所述,运算符
??
和||
之间的区别在于,一个检查 * null * 值,另一个检查 falsey 值。但是,在许多情况下,它们的行为相同。这是因为在JavaScript中,每个 nullish 值也是 falsey(但不是每个 falsey 值都是 nullish)。使用我们上面学到的知识,我们可以为不同的行为创建一些示例:
由于新的Nullish Coalescing Operator可以区分无值和假值,因此如果您需要检查是否没有String或空String,它可能是有益的。通常,您可能希望在大多数情况下使用
??
而不是||
。最后,也是最不重要的,这里有两个示例,它们的行为相同:
3ks5zfa03#
作为一个非常简短的规则,你可以用相反的方式来看待它:
||
(或)returns the first "truthy" value
(如果不存在“truthy”值,则为最后一个值)??
(nullish coalescing)returns the first "defined" value
(如果不存在“defined”值,则为最后一个值)示例
qltillow4#
如MDN中所述:
与逻辑OR(
||
)运算符相反,如果左操作数是一个非null
或undefined
的假值,则返回左操作数。换句话说,如果你使用||
为另一个变量foo
提供一些默认值,如果你认为一些错误的值是可用的,你可能会遇到意想不到的行为(例如:''
或0
)。更多示例见下文。在the answer to the question you linked中:
无论第一个操作数的类型如何,如果将其强制转换为Boolean结果为false,则赋值将使用第二个操作数。注意以下所有情况:
ktecyv1j5#
基于MDN docs:
与the logical OR (||) operator相反,如果左操作数是不是
null
或undefined
的falsy值,则返回左操作数。概念示例:
||
作为NOTundefined
或null
的 falsy 值时:??
用于上述情况时:phone
变量,在我们的表单中不是强制性的,空字符串(''
)对我们有效,如果phone
变量是null
或undefined
,我们想要doSomething()
,现在猜猜看:||
作为NOTundefined
或null
的 falsy 值时:??
用于上述情况时:注意:实际上这是一个示例,在真实的项目中你可以更好地了解这个可爱的操作用法。
注意事项:对于
undefined
或null
,它们的作用彼此类似。xxls0lw86#
null(ish)合并运算符 only 适用于
null
和undefined
。所以,当你不想要这些值,但你会接受其他的假值时,使用null(ish)合并运算符:逻辑OR将跳过任何假值,并给予你另一个东西。逻辑OR将跳过任何假值,并为您提供其他参数。Thisdoeswork,现在已经习惯了,但是它并不总是你想要的:
这里有一些规则,可以帮助你确定你需要哪一个。最简单的测试:
null
(和undefined
-通常是一样的)吗?然后使用??
。如果您不确定,最好默认为null合并运算符。0
或""
吗?然后使用||
。第二个是它实际上变得棘手的地方。你怎么知道你需要丢弃falsy值?好吧,第一个片段显示了如果你这样做会发生什么:
f(0)
将丢弃零,从而产生不同的结果。这是bug的一个常见来源。由于结构a = b || c
通常会引入一个回退值(在本例中为c
),因此当您无意时,它可能会意外地回退到它。如果您想为调用
updateAge()
(无参数)提供一个回退,则此方法有效,但如果您调用updateAge(0)
(无更新),则会失败。类似地,您可以:同样,这对
sayMyName()
有效(没有参数),但对sayMyName("")
失败(显式没有问候语)。概括地说,如果你提供了一个与falsy值 * 不同 * 的回退值,那么你可能会有问题。但是,如果你的后备 * 是 * falsy值-
num || 0
或str || ""
,那么这并不重要。很少(或者应该是)您可能会期望混合类型(数字,或字符串,或对象等)并提供一个回退:
input || fallback
有效,但会拒绝空字符串和零。这通常是错误的,除非你明确地不想要任何这些。简单地说,您应该始终使用空合并运算符
??
。这将是更少的认知负荷,以找出它是否是一个潜在的错误或没有。也没有太多的理由去避免它。它比布尔OR更新,所以它不能在旧的环境中工作,这是真的,但是现在你应该为那些编译你的代码。如果你不能或者不想这么做,那么你没有选择,应该使用布尔OR。l5tcr1uw7#
当
||
被用作布尔条件时,它将变为false。例如:逻辑OR仍然会为任何不计算为
true
的值给予下一个值。所以在这种情况下,它给出了21
的值。其中??
仅处理null
和undefined
。cgvd09ve8#
简而言之,当你关心让一个变量从一个可能的
null
undefined
源赋值,并且你希望为变量提供一个默认值时,使用空合并运算符??
。如果你不想在JavaScript定义falsytruthy [1]时把自己搞得一团糟,那么就避免使用||.
nullish coalescing operator ??
JavaScript definition of falsy
一真实的例子
[1]每一种编程语言都有自己对falsy truthy的定义。判断一个值是否是truthy值的基本方法是,如果显式类型转换函数
bool(value)
的结果是true
,则该值是 truthy。对于那些可能跨语言工作的,PHP和C#也有
??
。参见PHP、C#。