【问题标题】:Increasing understanding of JavaScript increment operator [duplicate]增加对 JavaScript 增量运算符的理解 [重复]
【发布时间】:2012-12-28 12:34:00
【问题描述】:

可能重复:
++someVariable Vs. someVariable++ in Javascript

我很难理解增量运算符。此运算符将其操作数递增(加一)并返回一个值。我在操作数 (x++) 之后使用了带有运算符的后缀,因此它在递增之前返回值。

所以如果 x 为 3,则语句 y = x++ 将 y 设置为 3 并将 x 递增为 4

var x = 3; 
var y = x++; 

console.log(x); // 4
console.log(y); // 3

我不明白为什么 y 不保存值 4 而是设置为 3,以及为什么 x 在分配值为 3 时保存值 4。

【问题讨论】:

  • x++ 在变量赋值后执行。所以y 得到x 的值,即3。然后x 的值增加1。留下x = 4y = 3
  • 来自MDN docs: "这个操作符递增(加一)它的操作数并返回一个值。如果使用后缀,操作数后面有操作符(例如,x++),那么它在递增之前返回值。[...]" ...现在清楚还是您正在努力解决?
  • 我建议你听从 Douglas Crockford 的建议,避免使用递增和递减运算符jslint.com/lint.html#inc

标签: javascript


【解决方案1】:

post-increment 运算符在 被取值后递增。这就是它与预增量运算符不同的原因。

【讨论】:

    【解决方案2】:
    var y = x++;
    

    是这两个语句的简写(按顺序):

    var y = x;
    x = x + 1;
    

    如果你想让 y 等于 4,你会这样做:

    var y = ++x;
    

    简写为:

    x = x + 1;
    var y = x;
    

    【讨论】:

      【解决方案3】:

      已通过关注Alex cmets 改进了问题。

      假设有一个变量x, s.a. var x=3.

      案例 1 当你写:

      var y = x++;
      

      然后,完成以下步骤:

      1. 变量x被求值(x为3);
      2. 变量x递增(x为4);
      3. 评估结果(发生在步骤(1)中)分配给y(因此将产生y=3);

      案例 2 当你写: 变量 y = ++x;

      然后,完成以下步骤:

      1. 变量x递增(x为4);
      2. 评估变量xx 为 4);
      3. 评估结果(发生在步骤(2)中)分配给y(因此将产生y=4);

      在这种情况下,遵循 Javascript 的运算符优先级很重要(例如,请参阅更多 here)。

      案例 3 为了完整起见,正如 Alex 所观察到的,同样重要的是要认识到,如果 CASE1 中提供的步骤对同一个变量重复,那么变量将递增然后恢复到初始值,即你写的时候:

      x = x++;
      

      然后,完成以下步骤:

      1. 变量x被求值(x是3);
      2. 变量x递增(x为4);
      3. 评估结果(发生在步骤(1)中)分配给x(因此将产生x=3);

      【讨论】:

      • 这是错误的。增量(post 和 pre)发生在分配之前。两者的区别在于增量发生在它们自己的评估之前还是之后。
      • 不不,你完全错了!见this fiddle。我还更新了答案以显示相同的示例。
      • 此外,您必须注意到我的答案与接受的答案相同。
      • 你的 jsfiddle 并不能证明什么。您在声明之后发出警报,那么这如何证明增量发生在分配之后?这是一个 sn-p,它显示 x 在 y 被赋值之前已经递增:var x = 0; var y = ( function( c ) { console.log( x ); console.log( y ); return c; }( x++ ) );控制台.log(y);接受的答案与此处的大多数答案一样不正确。
      • 不,y的值为3,即后增量前的值证明了这一点!同样,在 x 增加之后,z 的值就是 x。此外,考虑到 David Schwartz 和我写的一样:他也错了吗?
      【解决方案4】:

      来自MDN Docs - Arithmetic Operators

      ++(增量)

      自增运算符的用法如下:

      var++ 或 ++var

      此运算符将其操作数递增(加一)并返回一个 价值。如果使用后缀,则在操作数之后使用运算符(例如, x++),然后返回递增前的值。如果使用前缀 with 操作数之前的运算符(例如,++x),则返回 递增后的值。

      例如,如果 x 为 3,则语句 y = x++ 将 y 设置为 3,并且 将 x 递增到 4。如果 x 为 3,则语句 y = ++x 递增 x 为 4 并将 y 设置为 4。

      【讨论】:

        【解决方案5】:

        变量后的++是后自增运算符,表示在读取变量后执行自增。

        见:http://en.wikipedia.org/wiki/Increment_and_decrement_operators

        【讨论】:

        • 它不是在语句结束时递增,而是在(子)表达式求值后立即递增
        • @Alex 我修正了我的语言,现在这有意义吗?
        【解决方案6】:

        x++ 是 *post*increment 运算符。相当于:

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

        这是过去 C 时代的遗留物,人们喜欢编写如下代码:

         while(*dest++ = *src++);
        

        (翻译:将内存范围复制到第一个 0 字节)。还有一个 *pre*increment 运算符++ x 先递增,然后返回递增的结果。

        【讨论】:

          【解决方案7】:

          有两种增加方式

          var y = x++; // first make the allocation then the increasing
          // and
          var y = ++x; // first make the increasing then the allocation
          

          【讨论】:

            【解决方案8】:

            x++ 的增量发生在 x 的值的临时副本生成并返回临时副本之后。相反的是 ++x,它是一个增量并返回新值:

            var x = 3;
            var y = ++x; // y === 4
            

            引用ECMA 5.1:

            PostfixExpression : LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [没有 LineTerminator 此处] -- 70 © Ecma International 2011
            11.3.1 后缀增量运算符 产生式 PostfixExpression : LeftHandSideExpression [no LineTerminator here] ++ 被评估为 如下: 1. 令 lhs 为评估 LeftHandSideExpression 的结果。 2.如果满足以下条件,则抛出SyntaxError异常 true:  Type(lhs) is Reference 是 true  IsStrictReference(lhs) is true  Type(GetBase(lhs)) 是环境记录  GetReferencedName(lhs) 是“eval”或“arguments” 3. 让 oldValue 是 ToNumber(GetValue(lhs))。 4.让newValue为相加的结果 值 1 到 oldValue,使用与 + 运算符相同的规则 (见 11.6.3)。 5. 调用 PutValue(lhs, newValue)。 6. 返回旧值。

            【讨论】:

            • 这是错误的。增量(post 和 pre)发生在分配之前。两者的区别在于增量发生在它们自己的评估之前还是之后。
            • @Alex 这不是关于运算符优先级的问题。赋值运算符在增量运算符之前或之后。
            • 运算符优先级决定了运算符的计算顺序。前置和后置操作符的计算顺序相同。只是他们的实际评价不同而已。
            • @Alex 好吧,如果您能以比我更好的方式措辞,请随时编辑帖子或发布您自己的答案。因为你把我弄丢了,所以“评价”和“实际评价”有什么区别?
            • (啊!)他们的执行不同会更好的措辞。重复线程的公认答案是非常完美的恕我直言。
            【解决方案9】:
            var y = x++; 
            

            表示x递增,y被赋值为x的递增值。

            var y = ++x;
            

            表示x 递增,y 被分配了x 的预递增值。

            【讨论】:

            • 第二个例子是var y = ++x吗?
            • x 在分配给 y 之前会递增,即使在您的第一个示例中也是如此。只是 x++ 在增量之前计算为 x 的值。
            • 在 JS 中是这样吗?我知道它在 C# 中,但我认为这将是依赖于语言的特性,所以进行了广义解释。
            • var x = 0; var y = ( function( c ) { console.log( x ); return c; }( x++ ) );控制台.log(y); // 1 0 --- 是的,在 C 和其他一些语言中 ++ 是不同的(甚至是不可预测的)。但据我所知,没有普遍的解释。只是有几个不同的。它们都没有对错或比另一个更普遍。
            • 酷!谢谢你的解释:)
            猜你喜欢
            • 2017-07-06
            • 2023-03-26
            • 2012-11-23
            • 2016-02-02
            • 1970-01-01
            • 2019-09-25
            • 1970-01-01
            • 2017-06-23
            • 1970-01-01
            相关资源
            最近更新 更多