有人可以解释为啥条件运算符和赋值运算符一起使用时表现奇怪吗?

Posted

技术标签:

【中文标题】有人可以解释为啥条件运算符和赋值运算符一起使用时表现奇怪吗?【英文标题】:Can someone explain why the conditional operator and the assignment operator behave strangely when used together?有人可以解释为什么条件运算符和赋值运算符一起使用时表现奇怪吗? 【发布时间】:2020-08-18 22:17:40 【问题描述】:

谁能解释一下为什么下面的代码不会报错:

var x;
false ? null : x = 1;

根据MDN-operator precedence,conditional operator 的运算符优先级高于assignment operator, 这意味着上面的代码应该给出一个错误,因为它实际上被解析为:

var x;
(false ? null : x) = 1

但它没有给出错误,而这按预期工作:

var x;
x = 1 ? alert(x) : null;

上面的代码解析如下:

var x;
x = (1 ? alert(x) : null);

因为条件运算符具有更高的优先级,但是为什么在我的第一个代码中,如果条件运算符的优先级高于赋值运算符,它不会给出错误?

【问题讨论】:

【参考方案1】:

如果你看一下实际的语法,条件运算符的两个“分支”是赋值表达式。因此,

false ? null : x = 1;

被解析为

false ? (null) : (x = 1);

因为? :构造中的first表达式是语法中的短路表达式,所以表达式

x = 1 ? alert(x) : null;

被解析为

x = (1 ? alert(x) : null);

【讨论】:

好吧,表达式语法中的所有内容都受到运算符优先级的“影响”;它是语法的核心。为了解析一个条件表达式,解析器接受一个短路逻辑表达式,然后是?,然后是一个赋值表达式,然后是:,然后是另一个赋值表达式。当然,所有这些表达式都可以简单得多。 确实应该认为? 具有更高的优先级。这就是为什么您的第二个表达式会以它的方式工作的原因。一旦解析器通过接受? 发现存在条件表达式,它就可以接受带有: 分隔符的较低 优先级赋值表达式,因为语法使这一点明确。 逗号表达式不是赋值表达式;这是一个优先级较低的制作。 是的,没错。一旦你习惯了它,? :javascript 中就会非常有用。 这些名称基本上是语法表示运算符优先级的方式。 短路表达式 是一个可能涉及&&|| 运算符的表达式。这是有道理的,因为? 左侧的表达式是一个逻辑测试,用于查看要执行? : 的哪个分支。【参考方案2】:

因为条件运算符的优先级高于赋值运算符,所以您的第一个块本质上是

var x;
(false ? null : x ) = 1;

(false ? null : x ) 变成x 所以整个块变成了

var x;
x = 1;

如果是(true ? null : x ),那么第二行将等同于null = 1,这不是正确的语法,但我相信不会抛出错误。

【讨论】:

这显然是不正确的——jsbin.com/modugojidu/edit?js,console——没有抛出错误。 (false ? null : x ) 计算结果为 undefined 是的,我已经意识到我所犯的错误。

以上是关于有人可以解释为啥条件运算符和赋值运算符一起使用时表现奇怪吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Java 没有条件与和条件或运算符的复合赋值版本? (&&=, ||=)

为啥 Java 没有条件与和条件或运算符的复合赋值版本? (&&=, ||=)

为啥要使用三元运算符而不为“真”条件赋值 (x = x ?: 1)

为啥使用单个赋值运算符处理复制和移动赋值效率不高?

为啥条件运算符是右结合的?

自动生成默认/复制/移动 ctor 和复制/移动赋值运算符的条件?