JavaScript語法對{}的奇葩處理

JavaScript的語法有多坑,算是衆人皆知了。html

今天看到vczh的這條微博:http://weibo.com/1916825084/B7qUFpOKb ,數組

 代碼以下:瀏覽器

{} + [];    // 0
[] + {};    // "[object Object]"
{} + [] == [] + {};    // false
({} + [] == [] + {});    // true

 

這麼蛋疼的語法坑估計也只有 JavaScript 這樣的奇葩纔有。函數

相信對於絕大部分不研究 JavaScript 編譯器的童鞋,根本沒法理解。(至少我也是以爲難以想象)spa

後來看到有人在轉發中貼出了這篇文章,纔有點恍然大悟!.net

 

下面,咱們先看看這個代碼:code

{
    a: 1
}

相信大部分童鞋,第一眼都會認爲這是一個 對象直接量 htm

那這個代碼呢?對象

{
    var a = 1;
}

瀏覽器會提示語法錯誤嗎?blog

顯然不會!細想一下,咱們就會明白到,這是一個 語句塊

if (1) {
    var a = 1;
}

 

說到這裏,敏銳的你可能已經發現:JavaScript 中以「{」開頭,會存在二義性。即,它有多是一個 對象直接量,也多是一個 語句塊

那 JavaScript 的編譯器是怎麼處理這個二義性的?

爲了解決這個問題,ECMA 的方法十分簡單粗暴:在語法解析的時候,若是一個語句以「{」開頭,就只把它解釋成語句塊。

這真心是一個坑爹的處理方式!

那既然都是語句塊,那爲何 {a:1} 卻沒有語法錯誤?

其實在這裏,a 被解析器理解爲了 標籤標籤 是用來配合 break 和 continue 語句做定向跳轉的。

所以,這樣的寫法就會拋出異常:

{
    a: function () {}
}

由於 function () {}  不是函數聲明,也不是函數表達式。

 

到這裏,你們應該對 {} 的奇葩處理有了基本的概念。咱們再看回文章開始所提到的幾條語句:

{} + [];    // 0
[] + {};    // "[object Object]"
{} + [] == [] + {};    // false
({} + [] == [] + {});    // true

第一條,由於是「{」開頭,被解析器解析爲 語句塊,代碼能夠理解爲:

if (1) {}
+[]

因此返回值是 0 。

第二條,因爲「{」並不在語句的開頭,因此是一個正常的 對象直接量,空數組和空對象直接相加,返回 "[object Object]" 。

理解了第一第二條,第三條已經無需解釋了。

第四條,由於是「(」開始,第一個 {} 被解析爲 對象直接量 ,於是兩條公式相等,返回 true。

 

 

參考資料:

http://typeof.net/s/jsmech/02.html

 

 

本文做者:Maple Jan

本文連接:http://www.cnblogs.com/maplejan/p/3768010.html

相關文章
相關標籤/搜索