一元运算符“++”和“ - ”奇怪的情况

时间:2014-01-20 13:36:11

标签: javascript unary-operator

这是使用一元运算符“++”的测试情况:

var j = 0 ;
console.log(j);
j = j++;
console.log(j);

为此,输出为:

0
0

由于++运算符的位置在操作数的后面,所以它的优先级低于赋值的优先级,我希望“j”首先接收它自己的值(即0),但随后递增。那么为什么第二个console.log(j)调用仍显示“0”?

为了清楚起见,我知道解决方案是:

// 1)
j++;
// 2)
++j;
// 3)
j += 1;
// 4)
j = ++j;

但我需要知道为什么在这个特定情况下不进行增量步骤,而不是如何修复它!

5 个答案:

答案 0 :(得分:52)

使用后增量时,这是一种不直观(但不是“怪异”!)的行为。

声明j = j++执行此操作:

  1. 评估LHS
    • 在这种情况下,没有什么特别的事情发生,因为你只是命名一个变量,但情况可能并非总是如此,例如foo() = j++
  2. 评估RHS
    • 获取j(0)的当前值,并记住它作为结果;
    • 增加j(获得1);
  3. 将RHS分配给LHS
    • 回想起RHS评估j(0)的“记忆”值。
  4. 结果是无操作。

    这里的关键是评估整个RHS并执行后增量,最终分配之前。


    http://www.ecma-international.org/ecma-262/5.1/#sec-11.3.1
    http://www.ecma-international.org/ecma-262/5.1/#sec-11.13.1

答案 1 :(得分:10)

根据ECMA Specifications for Postfix Increment Operator

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

因此,很明显新值首先在lhs上设置(在这种情况下为j),并且返回旧值作为表达式的结果,再次设置回到j。所以,价值不会改变。

答案 2 :(得分:2)

++是让你知道你当时会从中得到什么价值

++j; // increment the value and then give it to me.
j++; // give me the value and then increment it.

所以你说

j = j++;

在j增加之前将j设置为j的值。

答案 3 :(得分:0)

j = j++表示首先将RHS值分配给LHS,然后将RHS增加1.另一方面,j = ++j表示将RHS增加1,然后将其分配给LHS

答案 4 :(得分:-3)

j ++表示首先分配,然后递增

++ j表示首先递增,然后指定

所以,

var j = 0 ;
console.log(j);
j = ++j;
console.log(j);

0
1