這裏有兩個關鍵瞭解JavaScript條件表達式和Java條件表達式的區別:
:
請在ECMAScript的5註釋規範的這個部分的底部閱讀注現在
http://es5.github.io/#x11.12
,請閱讀條件表達式Java規範部分:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25
你會注意到,作爲ECMAScript的5注狀態,在三元運算符第三個操作數在Java中不能只是任何舊的表達 - 它只能是一個條件表達式。但是,對於ECMAScript 5,第三個操作數可以是任何AssignmentExpression。
在Java規範進一步看,我們看到的是表達任何賦值表達式:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.27
但條件表達式或者是與三元操作符(......的條件表達式:?.. 。)或者只是一個ConditionalOrExpression(在ES5中稱爲LogicalOrExpression)(參見上面關於該信息的前兩個鏈接中的任何一個)。在什麼樣的ConditionalOrExpression可以在這裏是開始於Java的 「產業鏈」:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.24
在ECMAScript中5
在這裏:
http://es5.github.io/#x11.11
繼在表達類型的 「鏈」 落後ECMAScript 5規範(因爲它比Java規範更容易遵循)從條件表達式一直到基本上所有其他表達式,但分配表達式最終讓我們在開始 - 主表達式:
http://es5.github.io/#x11.1
兩個以上的代碼段的第二個操作數是主表達式:
1
這一切rigamarole(如果我是正確的)的結果是,在Java中,第三個操作數三元運算符不能是一項任務,但可以在JavaScript中使用。這就是爲什麼你的兩個例子在Java中失敗,而在JavaScript中卻只有第二個。
爲什麼第一個使用JavaScript而不是第二個?
operand1 ? operand2 : operand3;
像工作以下IIFE代碼(不實際上,但下面的代碼是的說明如何將上述工程):
(function() { if (operand0) return operand1; else return operand2;}());
所以:
false ? 1 : x = 2;
變成(再次,不是實際上 - 下面的代碼是說明性的上面的代碼):
(function() { if (false) return 1; else return x = 2;}());
然而,在第二個片斷,使用的括號的情況下,從分離出明確的條件表達式「= 2;」 :
(false ? 1 : x) = 2;
變成(再次,不實際上 - 下面的代碼是說明性的上面的代碼):
(function() { if (false) return 1; else return x;}()) = 2;
三元運算符的「行爲像例子IIFE函數調用」行爲將返回任何x是,並且這將是一個值,而不是無法指定的引用。因此錯誤。這將像下面的代碼(如果x === 3):
3 = 2;
顯然,一個不能這樣做。在Java中,我相信,第一個錯誤是因爲第三個操作符不能被賦值,第二個賦值錯誤,因爲你不能賦值(就像在JavaScript中一樣)。
至於運算符優先級,請看下面的代碼:
var x = 3;
console.log(false ? 1 : x); // ?: evaluates to "3"
console.log(false ? 1 : x = 2); // ?: evaluates to "2"
console.log(false ? 1 : x = 2, 4); // ?: evaluates to "2" - "2" and "4" arguments passed to log
console.log((false ? 1 : x = 2, 4)); // ?: evaluates to "4"
在上面的IIFE說明性代碼方面觀察時,前兩個是容易理解。
在第一行中x被評估,條件表達式評估爲3 - 這很容易。
在第二行中,我可以描述它的最佳方式是條件運算符(?:)甚至會導致將較低優先級的'='運算符評估爲完整表達式,這不是因爲(?:)具有較高的優先級,但是因爲規範說明':'後面的賦值表達式作爲AssignmentExpression被評估(包括'= 2'部分)。這種行爲在上面IIFE示例的return語句中看起來更清晰。至少使用JavaScript,不僅可以在第二個操作數中進行賦值,還可以在條件表達式的第三個賦值中進行賦值。
但是,在第三行中,在「x = 2」表達式中已經找到完整的賦值表達式,並且三元運算符將其用作完整的第三操作數,並且','運算符的優先級低於任何另一方面,我們得到等效於以下代碼:
console.log((false ? 1 : x = 2), 4);
在代碼的第四行,在括號中的console.log()語句內包封整個表達式帶來「 4' 到」?: '三元表達式作爲第三操作數的一部分。
下面的jsfiddles演示了上述與實時代碼的討論。請注意,前兩個具有相同的確切的錯誤打印 '2' 兩次後:
FIDDLE1
FIDDLE2
FIDDLE3
通知,即[條件運算](HTTP://es5.github .io /#x11.12)會返回值,而不是引用。 – Teemu
@Teemu - 其中_value_實際上可能是一個參考。例如'(false?func1:func2)();' – nnnnnn
@nnnnnn你說得對,雖然OP在這個例子中只有一個變量。其實你已經在你的回答中提到了這一點,只是對我的閱讀不好...... – Teemu