سؤال

Here's a test situation for using the unary operator "++":

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

For this, the output is:

0
0

Since the ++ operator's position is at the back of the operand, so its precedence is lower than the assignment's precedence, I would expect "j" to first receive the value of itself (i.e.0), but then be incremented. So why is the second console.log(j) call still showing "0"?

Just to be clear, I know that the solutions are:

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

But I need to know why the increment step is not conducted in this specific scenario, NOT how to fix it!

هل كانت مفيدة؟

المحلول

This is an unintuitive (but not "weird"!) behaviour when using post-increment.

The statement j = j++ does this:

  1. Evaluate the LHS
    • In this case, nothing special happens because you simply named a variable, but this may not always be the case, e.g. foo() = j++
  2. Evaluate the RHS
    • Take the current value of j (0), and remember it as the result;
    • Increment j (to get 1);
  3. Assign the RHS to the LHS
    • recall that the RHS evaluates to that "remembered" value of j (0).

The result is a no-op.

The key here is that the entire RHS is evaluated and the post-increment performed, before the final assignment.


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

نصائح أخرى

According to the ECMA Specifications for Postfix Increment Operator,

  1. Let lhs be the result of evaluating LeftHandSideExpression.
  2. Throw a SyntaxError exception if the following conditions are all true:
    1. Type(lhs) is Reference is true
    2. IsStrictReference(lhs) is true
    3. Type(GetBase(lhs)) is Environment Record
    4. GetReferencedName(lhs) is either "eval" or "arguments"
  3. Let oldValue be ToNumber(GetValue(lhs)).
  4. Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 11.6.3).
  5. Call PutValue(lhs, newValue).
  6. Return oldValue.

So, it is clear that the new value is first set on the lhs (in this case j) and the the old value is returned as the result of the expression, which is again set back in j. So, the value doesn't change.

Where the ++ is lets you know what value you are going to get from it at that moment

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

so you were saying

j = j++;

set j to the value of j before it was incremented.

j = j++ means assign RHS value first to LHS and then increment RHS by 1. On the other hand, j = ++j means increment RHS by 1 and then assign it to LHS

j++ means at first assign,then increment

++j means at first increment,then assign

So,

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

0
1
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top