2

In JavaScript (JS), ++ has higher precedence than += or =. In trying to better understand operator execution order in JS, I'm hoping to see why the following code snippet results in 30 being printed?

let i = 1
let j = (i+=2) * (i+=3 + ++i);
console.log(j); //prints 30

Naively, it seems like the i+=2 is executing first, resulting in 3 * (i+=3 + ++i), and then 3 is being used as the starting value for i for both the i+=3 and ++i (resulting in 3 * (6 + 4)). But I'm wondering, if that is the case, why either the ++i or i+=3 is not having its side effect in assigning to i occur before the other executes?

9
  • 3
    Your expression might have defined semantics in JavaScript, but using the same variable with two post-increment operations in the same larger expression is a very fragile way of writing code. Instead of knowing how it works, just don't do it. (I'm pretty sure that in C++ it's explicitly an undefined behavior.) Commented Jun 21, 2023 at 19:41
  • 5
    I mean, think about it. What if you saw that code in stuff you were trying to debug that was written 2 years ago? Just because you can do something doesn't mean you should. Commented Jun 21, 2023 at 19:42
  • 2
    Sure, thanks for the info; just trying to understand execution order in general as I am learning the language, and this was something I experimented with. Commented Jun 21, 2023 at 19:43
  • 2
    To me it's best to step back and think, "What are the computational semantics I'm trying to express here? Why would I sit down with pencil and paper and dream up something like this?" Commented Jun 21, 2023 at 19:54
  • 4
    (i+=3 + ++i) is the same as i += (3 + ++i) not (i+=3) + (++i) Commented Jun 21, 2023 at 19:59

1 Answer 1

2

Summary of the discussion in comments:

Simplified example:

let i = 1
let j = i += 3 + ++i;
console.log(j); //prints 6

i += 3 + ++i is the same as i += (3 + ++i) and not (i += 3) + (++i)

In the ECMAScript specification we can read that left-hand side expression is evaluated first

  1. Let lref be ? Evaluation of LeftHandSideExpression.

Then after right-hand side calculations in step 7

  1. Let r be ? ApplyStringOrNumericBinaryOperator(lval, opText, rval).

So i += (3 + ++i) is really:

let lhs = i // 1
let rhs = 3 + ++i // 3 + 2
i = lhs + rhs // 6

or in thee example from the question:

let lhs = i // 3
let rhs = 3 + ++i // 3 + 4
i = lhs + rhs // 10
Sign up to request clarification or add additional context in comments.

1 Comment

another thing to consider is the parentheses of the first part. I don't think the confusion was with just the second part but with the whole expression. so for example if you do the original (i+=2) * (i+=3 + ++i) it results in 30, but i+=2 * (i+=3 + ++i) results in 13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.