【问题标题】:++ operator returns original value if placed after operand — how?++ 运算符如果放在操作数之后返回原始值 - 如何?
【发布时间】:2012-12-01 14:14:32
【问题描述】:

据我所知,x++ 本质上是x = x + 1 的一种更简洁的表达方式。到目前为止,很清楚。在前端 Javascript 中,我偶尔会看到 ++x — 我似乎记得从我无法再找到的 jsPerf 测试中(Google ++ 如何有效?),这在某种程度上具有很小的性能优势特定版本的 IE,然后放手。

但是我最近遇到了一些关于执行顺序(JS 代码)的奇怪怪癖:

var x = 1;
console.log(x++); // 1 (?!)
console.log(x);   // 2

……而

var x = 1;
console.log(++x); // 2 (what I would've expected)
console.log(x);   // 2

我无法理解这一点。当操作和赋值在括号内时,我们如何返回未修改的变量,因此所有权利都应该在调用console.log之前执行,更不用说执行和返回了?

【问题讨论】:

  • 具有所描述行为的运算符可以追溯到至少到 1970 年代的 C。
  • pdp-11(以及随后的 VAX 机器)具有前置和后置增量寄存器间接寻址模式。多年来,IBM 360/370 指令集以及其他各种处理器可能也是如此。
  • 此类内容最有效的搜索词是“ecmascript 规范”
  • @PaulButcher 并非所有这些其他答案都表明这是一个通用功能而不是 ECMAscript 怪癖。在谷歌上搜索像++ 这样的特殊字符似乎是不可能的。它似乎将它们视为搜索查询中的运算符,标准转义序列没有明显效果。
  • 这个特定的运算符在许多语言中都是相同的,但对于所有运算符和所有语言来说不一定都是如此。如果您想知道运算符在特定语言中的行为方式,那么找出它的最佳方法是搜索该语言的规范。然后,您可以在规范文档中对运算符执行文本搜索。然后,如果您想知道其他语言的行为方式是否相同,您将找到第 11.3 和 11.4 节,它们为您提供了可搜索的术语。

标签: javascript operators variable-assignment execution order-of-execution


【解决方案1】:

这是两个不同的东西

x++

是一个后增量。它在更改之前返回x,然后更改它:

tmp = x;
x = x+1;
return tmp;

++x

是一个预增量。它首先更改x,然后返回新值:

x = x+1;
return x;

第二个也稍微快一些,因为您的编译器/解释器不需要创建临时变量并复制数据。

【讨论】:

  • 第二个也稍微快一些,因为您的编译器/解释器不需要创建临时变量并复制数据。 Not necessarily
  • 感谢内部工作原理的解释,证明了性能问题的合理性!但我仍然对执行顺序感到困惑——究竟什么时候分配回代码可访问变量?例如,将操作包装在括号中仍会返回未修改的变量。强制分配所需的最低执行级别是多少?
  • @Barney - 阅读我之前评论中的链接。它深入介绍了运算符,并解释了 postfix 如何需要功能分解,但 prefix 可能不需要。
  • 感谢@kojiro — 螺母和螺栓正是我所追求的。
【解决方案2】:

您说的是 pre-post- increment operators 之间的区别。在前一种情况下,操作本质上是(x = x + 1; yield x),在第二种情况下,它是(yield x; x = x + 1)

【讨论】:

    【解决方案3】:

    x++ 获取值,然后将其递增。

    ++x 增加值,然后获取它。

    这是我使用过的每种语言中支持这些运算符的行为。

    【讨论】:

      【解决方案4】:

      在变量之后使用 ++ 会增加该行代码之后的值。

      同样,使用 ++ BEFORE 变量会在该行代码中使用它之前递增值。

      很酷吧?

      var x = 1;
      x++;
      console.log(x++); // 2 (?!)
      console.log(x);   // 3
      console.log(++x); // 4
      console.log(x++); // 4
      console.log(x);   // 5
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-12
        • 2011-03-14
        • 2018-11-28
        • 1970-01-01
        • 2010-12-13
        • 2011-01-03
        • 1970-01-01
        相关资源
        最近更新 更多