Javascript中的预增量

时间:2014-05-29 10:00:11

标签: javascript pre-increment

我刚刚在Javascript中遇到了关于预增量的'功能'。在我使用的所有其他语言中,它就像我认为的那样。例如。在C ++中:

#include <iostream>

int main()
{
    int i = 0;

    i += ++i;

    std::cout << i << std::endl; // Outputs 2.
}

因此,++i不会复制变量,因此输出为2。

在PHP中相同:

<?php

$i = 0;

$i += ++$i;

echo $i; // Outputs 2.

然而,在Javascript中:

var i = 0;

i += ++i;

console.log(i); // Outputs 1.

所以看起来在Javascript中,它会复制i并且不会引用变量。这是故意的,如果是,为什么?

2 个答案:

答案 0 :(得分:7)

来自EcmaScript标准:

  

11.4.4前缀增量运算符

     

生产UnaryExpression:++ UnaryExpression的评估如下:

     
      
  1. 让expr成为评估UnaryExpression的结果。
  2.   
  3. 如果满足以下条件,则抛出SyntaxError异常:�   
        
    • Type(expr)是Reference is true
    •   
    • IsStrictReference(expr)为真
    •   
    • Type(GetBase(expr))是环境记录
    •   
    • GetReferencedName(expr)是&#34; eval&#34;或者&#34;论证&#34;
    •   
  4.   
  5. 让oldValue为ToNumber(GetValue(expr))。
  6.   
  7. 让newValue成为将值1添加到oldValue的结果,使用与+运算符相同的规则(见11.6.3)。
  8.   
  9. 调用PutValue(expr,newValue)。
  10.   
  11. 返回newValue。
  12.   

  

11.13.2化合物分配(op =)

     

生产AssignmentExpression:LeftHandSideExpression AssignmentOperator AssignmentExpression,其中AssignmentOperator是@ =,@代表上面指出的一个运算符,评估如下:

     
      
  1. 让lref成为评估LeftHandSideExpression的结果。
  2.   
  3. 让lval成为GetValue(lref)。
  4.   
  5. 让rref成为评估AssignmentExpression的结果。
  6.   
  7. 让rval为GetValue(rref)。
  8.   
  9. 设r是将operator @应用于lval和rval的结果。
  10.   
  11. 如果满足以下条件,则抛出SyntaxError异常:   
        
    • Type(lref)是Reference is true
    •   
    • IsStrictReference(lref)为真
    •   
    • 类型(GetBase(lref))是环境记录
    •   
    • GetReferencedName(lref)是&#34; eval&#34;或者&#34;论证&#34;
    •   
  12.   
  13. 调用PutValue(lref,r)
  14.   

因此,var i = 0; i += ++i是:

i = 0;
lvalue = value(i), which is 0;
rvalue = value(++i), which is: increment i, then value of i (1);
thus, rvalue = 1;
i = lvalue (0) + rvalue (1), which is 1.

完全符合规范。

但是,在C ++中,这被明确定义为未定义的行为,因此在不同的编译器上,您可能也会获得1.或99.或者它可能会使您的计算机着火。所有这些都是符合标准的编译器。因此,大多数人会建议你只在声明中使用一次/后增量变量。

答案 1 :(得分:0)

我认为这是因为javascript看到var i = 0; i += ++i;就是这样:

var i = 0;
++i = 1;
i += 1;

这是因为++i在执行+=之前将i变为1,所以它0 + 1 = 1

事实上,我越是想到它,为什么还要做其他事情?

发生了两项任务,一项必须在另一项之前完成。所以这两个选项可能是:

  • 首先执行++,并使其成为i = i + 1,其中i从0开始并等同 到1

  • 执行+ = first,并将其设为i = 0 +(++ i),这也等同于 1