【问题标题】:Javascript increment operation order of evaluationJavascript递增运算顺序求值
【发布时间】:2016-03-09 18:34:39
【问题描述】:

我知道后缀/前缀递增/递减运算符的作用。而在 javascript 中,这似乎没有什么不同。

虽然我可以很容易地猜到这一行的结果:

var foo = 10; console.log(foo, ++foo, foo, foo++, foo); 
// output: 10 11 11 11 12

++ 运算符出现在单独的表达式中。

因为这些运算符出现在同一个表达式中,所以有点复杂:

var foo = 10; console.log(foo, ++foo + foo++, foo);
// output[1]: 10 22 12
// Nothing unexpected assuming LTR evaluation

var foo = 10; console.log(foo, foo++ + ++foo, foo);
// output[2]: 10 22 12
// What? Ordering is now different but we have the same output.
// Maybe value of foo is evaluated lazily...

var foo = 10; console.log(foo, foo + ++foo, foo);
// output[3]: 10 21 11
// What?! So first 'foo' is evaluated before the increment?

我的问题是,Javascript(在这种情况下是 V8,因为我在 Chrome 中测试了这些)最终如何以不同的方式评估第二个和第三个示例中的加法表达式?

为什么foo 最终的评估结果与foo++ 不同。后缀 ++ 不应该在表达式之后递增,并在表达式内计算为 foo 吗?

【问题讨论】:

  • 我相信您所描述的行为表明,在 javascript 中,加法是左关联。这意味着首先计算 left_expression + right_expression 中的左表达式。我相信,增量运算符的行为方式符合您的预期。

标签: javascript increment operator-precedence


【解决方案1】:

看看:

foo++ + ++foo

把它改写成:

foo++ →
    addition_lhs = foo  // addition_lhs == 10
    foo += 1            // foo == 11
++foo →
    foo += 1            // foo == 12
    addition_rhs = foo  // addition_rhs == 12

addition_lhs + addition_rhs == 10 + 12 == 22

还有foo + ++foo:

foo →
    addition_lhs = foo  // addition_lhs == 10
++foo →
    foo += 1            // foo == 11
    addition_rhs = foo  // addition_rhs == 11

addition_lhs + addition_rhs == 10 + 11 == 21

所以一切都是从左到右评估的,包括增量。

要理解的关键规则是,在 JavaScript 中,整个左侧 (LHS) 会被执行,并在右侧 (RHS) 上完成任何操作之前记住值。

您可以通过reading the standard 确认评估顺序,或者只是在您的表达式中放置一个运行时错误,然后看看会发生什么:

alert(1) + alert(2) + (function () { throw Error(); })() + alert(3)

【讨论】:

  • 所以我只需要知道增量发生在子表达式之后(a 之后,然后在a + b 中的b 之后),而不是完整表达式(a + b 之后)。说得通。谢谢!
【解决方案2】:

var foo = 10; console.log(foo, ++foo + foo++, foo);

++foo + foo++
   11 + 11

预增量将 foo 设置为 11,然后将其再次添加到 foo,仍然为 11,在 foo 再次递增之前评估为 22。

var foo = 10; console.log(foo, foo++ + ++foo, foo);

foo++ + ++foo
10    +    12

当我们到达 ++foo 时,该值已经从 foo++ 中获得了罪名

var foo = 10; console.log(foo, foo + ++foo, foo);

foo + ++foo
10  +   11

foo 在我们将它添加到 foo 之前递增,因此给我们 10 + 11

摘要

基本上,这完全取决于将它们加在一起时 foo 的当前值是多少。

【讨论】:

    【解决方案3】:

    了解当您使用foo++ 时,您是在告诉“编译器”:将其压入堆栈后,将其递增。当您使用++foo 时,您是在说另一种方式:递增它然后将其推入堆栈。 ++ 运算符优先于 +,因为“编译器”以这种方式读取表达式 (foo++)+(++foo)

    【讨论】:

      猜你喜欢
      • 2020-08-15
      • 1970-01-01
      • 2022-06-16
      • 2010-11-29
      • 2011-11-03
      • 2021-08-23
      • 2021-07-12
      • 1970-01-01
      • 2014-12-11
      相关资源
      最近更新 更多