JavaScript 运算符优先级、赋值和递增?

JavaScript Operator Precedence, Assignment, and Increment?

提问人:mishar 提问时间:6/22/2023 最后编辑:mplungjanmishar 更新时间:6/22/2023 访问量:51

问:

在 JavaScript (JS) 中,具有比 或 更高的优先级。为了更好地理解 JS 中的运算符执行顺序,我希望看到为什么以下代码片段会导致被打印?+++==30

let i = 1
let j = (i+=2) * (i+=3 + ++i);
console.log(j); //prints 30

幼稚地认为,似乎 首先执行,导致 ,然后被用作 和 的起始值(导致 )。但我想知道,如果是这样的话,为什么 or 在另一个执行之前分配没有副作用?i+=23 * (i+=3 + ++i)3ii+=3++i3 * (6 + 4)++ii+=3i

javascript 赋值运 顺序 前缀运算符

评论

3赞 Pointy 6/22/2023
您的表达式可能在 JavaScript 中定义了语义,但在同一个较大的表达式中使用具有两个增量后操作的同一变量是一种非常脆弱的代码编写方式。与其知道它是如何工作的,不如不要去做。(我很确定在 C++ 中它明确是一种未定义的行为。
5赞 Pointy 6/22/2023
我的意思是,想想看。如果您在尝试调试的 2 年前编写的内容中看到该代码怎么办?仅仅因为你可以做某事并不意味着你应该做
2赞 mishar 6/22/2023
当然,感谢您提供的信息;只是在我学习语言时试图理解一般的执行顺序,这是我尝试过的东西。
2赞 Pointy 6/22/2023
对我来说,最好退后一步想,“我在这里试图表达的计算语义是什么?我为什么要坐下来拿着铅笔和纸,想象出这样的事情呢?
4赞 Konrad 6/22/2023
(i+=3 + ++i)与不相同i += (3 + ++i)(i+=3) + (++i)

答:

2赞 Konrad #1

评论中的讨论摘要:

简化示例:

let i = 1
let j = i += 3 + ++i;
console.log(j); //prints 6

i += 3 + ++i是相同的,而不是i += (3 + ++i)(i += 3) + (++i)

ECMAScript 规范中,我们可以读到首先计算左侧表达式

  1. 让 lref 成为 ?LeftHandSideExpression 的计算结果。

然后在步骤中进行右侧计算后7

  1. 让 r 是 ?ApplyStringOrNumericBinaryOperator(lval, opText, rval)。

所以真的是:i += (3 + ++i)

let lhs = i // 1
let rhs = 3 + ++i // 3 + 2
i = lhs + rhs // 6

或者从问题中举例说明:

let lhs = i // 3
let rhs = 3 + ++i // 3 + 4
i = lhs + rhs // 10

评论

1赞 Fraŋkini 6/22/2023
要考虑的另一件事是第一部分的括号。我不认为混乱只在于第二部分,而在于整个表达。例如,如果你做原始的,它的结果是 30,但结果是 13(i+=2) * (i+=3 + ++i)i+=2 * (i+=3 + ++i)