最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript increment operation order of evaluation - Stack Overflow

programmeradmin4浏览0评论

I know the what the postfix/prefix increment/decrement operators do. And in javascript, this seems to be no different.

While I can guess the oute of this line easily:

var foo = 10; console.log(foo, ++foo, foo, foo++, foo); 
// output: 10 11 11 11 12

as ++ operators appear within separate expressions.

It gets a bit plicated as these operators appears within the same expression:

var foo = 10; console.log(foo, ++foo + foo++, foo);
// output[1]: 10 22 12
// Nothing unexpected assuming LTR evaluation

var foo = 10; console.log(foo, foo++ + ++foo, foo);
// output[2]: 10 22 12
// What? Ordering is now different but we have the same output.
// Maybe value of foo is evaluated lazily...

var foo = 10; console.log(foo, foo + ++foo, foo);
// output[3]: 10 21 11
// What?! So first 'foo' is evaluated before the increment?

and my question is, how does Javascript (V8 in this case, as I tested these in Chrome) end up evaluating the addition expression in 2nd and 3rd example differently?

Why does foo end up evaluating differently than foo++. Isn't postfix ++ supposed to increment after the expression and just evaluate to foo within expression?

I know the what the postfix/prefix increment/decrement operators do. And in javascript, this seems to be no different.

While I can guess the oute of this line easily:

var foo = 10; console.log(foo, ++foo, foo, foo++, foo); 
// output: 10 11 11 11 12

as ++ operators appear within separate expressions.

It gets a bit plicated as these operators appears within the same expression:

var foo = 10; console.log(foo, ++foo + foo++, foo);
// output[1]: 10 22 12
// Nothing unexpected assuming LTR evaluation

var foo = 10; console.log(foo, foo++ + ++foo, foo);
// output[2]: 10 22 12
// What? Ordering is now different but we have the same output.
// Maybe value of foo is evaluated lazily...

var foo = 10; console.log(foo, foo + ++foo, foo);
// output[3]: 10 21 11
// What?! So first 'foo' is evaluated before the increment?

and my question is, how does Javascript (V8 in this case, as I tested these in Chrome) end up evaluating the addition expression in 2nd and 3rd example differently?

Why does foo end up evaluating differently than foo++. Isn't postfix ++ supposed to increment after the expression and just evaluate to foo within expression?

Share Improve this question edited Dec 4, 2015 at 18:40 Kijewski 26.1k14 gold badges107 silver badges147 bronze badges asked Dec 4, 2015 at 18:20 ntplntpl 1556 bronze badges 1
  • I believe the behavior you are describing shows that in javascript, addition is left associative. This means that the left expression in left_expression + right_expression is evaluated first. The increment operator is behaving in the way that you expect, I believe. – Frank Bryce Commented Dec 4, 2015 at 18:28
Add a ment  | 

3 Answers 3

Reset to default 8

Just look at:

foo++ + ++foo

Mentally rewrite it to:

foo++ →
    addition_lhs = foo  // addition_lhs == 10
    foo += 1            // foo == 11
++foo →
    foo += 1            // foo == 12
    addition_rhs = foo  // addition_rhs == 12

addition_lhs + addition_rhs == 10 + 12 == 22

And foo + ++foo:

foo →
    addition_lhs = foo  // addition_lhs == 10
++foo →
    foo += 1            // foo == 11
    addition_rhs = foo  // addition_rhs == 11

addition_lhs + addition_rhs == 10 + 11 == 21

So everything is evaluated left to right, including the incrementation.

The crucial rule to understand is that in JavaScript the whole left hand side (LHS) is executed, and the value memorized, before any operation gets done on the right hand side (RHS).

You can either confirm the evaluation order by reading the standard or just place a runtime error in your expression and look what happens:

alert(1) + alert(2) + (function () { throw Error(); })() + alert(3)

Understand that when you use foo++ you're telling to the "piler": after you push it to the stack, increment it. When you use ++foo you're telling the other way: increment it then push it to the stack. The ++ operator have preference over the +, since the "piler" read the expression this way (foo++)+(++foo)

var foo = 10; console.log(foo, ++foo + foo++, foo);

++foo + foo++
   11 + 11

The pre increment sets foo to 11 then adds it to foo again which is still 11, evaluating to 22 before foo is again incremented.

var foo = 10; console.log(foo, foo++ + ++foo, foo);

foo++ + ++foo
10    +    12

By the time we reach ++foo, the value has already incriminated from foo++

var foo = 10; console.log(foo, foo + ++foo, foo);

foo + ++foo
10  +   11

foo is incremented before we add it to foo, thus giving us 10 + 11

SUMMARY

Basically it all depends on what the current value of foo is when you add them together.

发布评论

评论列表(0)

  1. 暂无评论