2015-12-04 79 views
4

我知道後綴/前綴增量/減量運算符的作用。而在JavaScript中,這似乎沒有什麼不同。評估的Javascript增量操作順序

雖然我可以猜到此行的結果很容易:

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

++運營商單獨出現在表達式中。

它變得有點複雜,因爲這些運營商出現在同一個表達式中:

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? 

,我的問題是,如何使用Javascript(V8在這種情況下,我測試了這些在Chrome)最終評估在第二和第三個例子中的加法表達是不同的

爲什麼foo的結果與foo++的結果不同。不是後綴++應該在表達式後遞增,並且只在表達式內求值爲foo

+0

我相信你的描述顯示了行爲在JavaScript中,除了是*左*關聯。這意味着首先評估'left_expression + right_expression'中的左表達式。我相信,增量操作符的行爲方式與您期望的相同。 –

回答

6

只要看看:

foo++ + ++foo 

它精神上改寫爲:

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 

而且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 

所以一切都是從左向右計算的,包括遞增。

要理解的關鍵規則是JavaScript中執行左手側(LHS),並在右側(RHS)完成任何操作之前存儲值。

您可以通過reading the standard確認評估順序或只是放置一個運行時錯誤在你的表情,看看會發生什麼:

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

所以我只需要知道在子表達式之後立即發生增量(在'a + b'中'a'之後'b之後),而不是完整表達式(在'a + b'之後)。 有道理。謝謝! – ntpl

1

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

++foo + foo++ 
    11 + 11 

預增量設置FOO至11然後將它再次foo的這仍然是11,評估22之前FOO被再次遞增。

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

foo++ + ++foo 
10 + 12 

通過我們達到++ FOO的時間,該值已經從富++

變種富= 10牽連; console.log(foo,foo + ++ foo,foo);之前,我們把它添加到富,從而使我們的10 + 11

摘要

基本上這一切都取決於foo的電流值是當你

foo + ++foo 
10 + 11 

FOO遞增將它們加在一起。

2

明白,當你使用foo++你告訴的「編譯」:將它推入堆棧後,增加它。當你使用++foo時,你會以另一種方式告訴它:增加它然後將它推入堆棧。 的++運營商有過+偏好,因爲「編譯」閱讀表達這樣(foo++)+(++foo)