无效合并和三元的运算符优先级

Operator precedence of nullish coalescing and ternary

有人可以解释为什么 result 在此语句中计算为 20 吗?

let result = 10 ?? true ? 20 : 30;

鉴于无效合并以从左到右的方式评估语句并且比三元运算符更高 precedence,为什么不假设 result 应该是 10?

注意:如果加了分组运算符,那么result就是10

let result = 10 ?? (true ? 20 : 30);

如上面 blex 的评论所述,该语句只是将合并操作减少到值 10,然后计算 10 ? 20 : 30。由于 10 是一个真值,这里的三元运算将 return 为真值,即 20.

按我的理解,一个nullish coalescing operator (??) has a higher operator presedence than a conditional (ternary) operator,所以应该先执行。

docs 表示 ?? 运算符的运算符优先级得分为 5,而 ... ? ... : ... 的得分为 4。)

所以

let result = 10 ?? true ? 20 : 30;

基本上评估为

let result = (10 ?? true) ? 20 : 30; // => 10 ? 20 : 30

鉴于 10 是一个 truthy 值,它 (10 ? 20 : 30) 的计算结果为 20

额外的细节

您可能会注意到 “关联性” 列在 JavaScript table of operator presedence

你可能想知道它是否在这种情况下起作用。但答案似乎是它没有。以下引述(来自文档)说明了这一点:

The difference in associativity comes into play when there are multiple operators of the same precedence.

Source

不会出现将无效合并和三元组合在一起的情况。看看这个例子:

a ?? false ? 'foo' : 'bar'

如果a为真,则a被选中,显然返回'foo'
如果 a 为空值,即 null, undefined,则选择 false,并返回 'bar'
如果 a 是其他虚假值,即 '', 0, false,则选择 a。但是,a在三元的角度仍然是假的,因此返回'bar'
如果要对条件语句进行无效检查,请改用:

a != null ? 'foo' : 'bar' // a is not null or undefined
!a && a != null ? 'bar' : 'foo' // a is not '', 0, or false. Does anyone really use this one?