2016-07-28 217 views
22

我有一個雙重問題,涉及到一些我認爲是不正確的Javascript代碼的問題。Javascript中括號內逗號的行爲

以下語句是如何在Javascript中解釋的?爲什麼?

(1,2,3,4) 

爲什麼會出現這兩個調用之間的區別:這將導致a等於4Uncaught TypeError: a is not a function被拋出

var a = (1,2,3,4); 
a(); 

,並

(1,2,3,4)(); 

導致Uncaught TypeError: (((1 , 2) , 3) , 4) is not a function

+1

閱讀更多關於逗號運算符[here](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Comma_Operator)。 – Arnauld

+2

沒有區別。在這兩種情況下,我都會在FireFox中得到'4不是函數'.. –

+0

對我來說看起來像一個鉻錯誤。 – georg

回答

14

How is the following statement interpreted in Javascript, and why?

(1,2,3,4) 

這是包裹在分組圓括號的逗號運算表達(實際上,它們的鏈)。逗號運算符是非常不尋常的:它會對它的兩個操作數進行評估,然後將第二個值作爲它的值,從而丟棄第一個值。你有一個它們的鏈,所以評估1的值,然後是2,然後是3,然後是4,而逗號運算符鏈的結果是值4;分組括號表達式的結果因此是4.

Why is there a difference between these two invocations:

var a = (1,2,3,4); 
a(); 

由於該語言的語法。在第一種情況下,這顯然不是函數調用,因爲在調用第一個(之前沒有值。像JavaScript這樣的複雜語言的解析規則就是這樣:複雜。解析器是上下文相關的,並且知道如何區分組合括號和函數調用括號。

which leads to a being equal to 4 and Uncaught TypeError: a is not a function being thrown, and

(1,2,3,4)(); 

which leads to Uncaught TypeError: (((1 , 2) , 3) , 4) is not a function?

在這兩種情況下,錯誤消息都是引用了表達式,該表達式產生了隨後嘗試調用的函數作爲函數。

+2

這並不真正回答問題的第二部分。爲什麼'(1,2,3,4)()'的錯誤信息很奇怪?如果我做了類似'(1 + 2)()'的操作,我會收到一條消息,說「3不是函數」,而不是「(1 + 2)不是函數」。如果我做了'(1 + 2,3)()'這樣的事情,我得到的信息是'(3,3)'而不是'3'或'(1 + 2,3)'。似乎逗號運算符評估被暫停,或者錯誤信息以奇怪的方式產生。 – user2357112

+3

第二個想法是,如果你只是比較'a()'和'(1,2,3,4)()',我想它看起來像剛剛解析並解析了它試圖調用的表達式的JavaScript引擎。進一步的實驗顯示了很多其他奇怪的情況,至少Chrome的錯誤消息是壞的函數調用,所以我不知道這個答案是否值得深入挖掘。 – user2357112

+4

@ user2357112查看[ES6表達語法](http://www.ecma-international.org/ecma-262/6.0/#sec-expressions),它看起來像任何一種* ShiftExpression *都包含其評估值在錯誤信息中。任何類型* Expression *不是* ShiftExpression *在錯誤消息中都有解析的,未評估的文本。比較'(1 || 2 || 3 || 4)()'與'(1 + 2 + 3)()'或'(1 << 2)()'(第一種不是一種ShiftExpression ',後兩個是)。這似乎只是Chrome的解析器或錯誤記者的一個怪癖。 – apsillers

6

在JS(其他語言)中有一個運算符叫做逗號運算符。它只需要兩個操作數,並返回最右邊的一個。

a = 1, 2; // a now equals 2 

它是,但是,不相同逗號作爲函數參數隔板。它是一個操作員。

+1

這並不真正回答問題的第二部分。 – user2357112

4

The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.

因此,語句(1,2,3,4);返回4,所以var a = (1,2,3,4);意味着a等於4其中,不是一個函數,從而該錯誤。

同樣,(1,2,3,4)只是逗號運算符的分組而不是函數,因此是第二個錯誤。

+1

雖然你沒有回答第二個問題。 – VisioN

+0

@VisioN Yup,更新。謝謝你讓我誠實:) – rgthree

相關問題