前段時間調試代碼,查看對象的toString的返回數據,因爲比較簡單,直接在瀏覽器的控制檯輸出代碼javascript
{}.toString(); // Uncaught SyntaxError: Unexpected token .
「.」不是期待的表達式,{}在JS中不是一個再正常不過的對象麼,因而試了一下其餘對象類型數據。html
[].toString(); // "" function(){}.toString(); // Uncaught SyntaxError: Unexpected token ( /^\.$/.toString(); // "/^\.$/"
查資料看了一下,總的來講涉及到JS這門語言設計的幾個概念:語句、函數聲明、語句塊等java
JS中,應用程序是由許多 語法正確的語句組成的,語句的做用就是告訴瀏覽器應該怎樣執行程序。語句之間使用「;」做爲結尾,其中主要包括表達式語句、塊語句、空語句和聲明語句,這裏不細講。
注意上面一段話中的語法正確一詞,在前言的demo代碼中,數組和正則表達式能夠正常調用的,可是對象和方法類型調用倒是失敗的,網上大部分答案回答都比較淺顯:」JS中語句不能以function或者大括號做爲開始,會報錯「。對於這句話,只能說對錯一半吧!正則表達式
先來講一下爲何語句不能以」function「開始,這裏涉及到函數聲明的概念。express
函數聲明:定義一個具備指定參數的函數,以function開頭, 其中包括函數名,參數名,和函數語句塊
舉個栗子?:數組
function funcName(arg1, arg2) { // 語句塊 }
咱們代碼中調用toString方法」function(){}.toString「,是以」function「開頭的, JS中會將以」function「 開頭的語句認定爲函數聲明語句,那麼代碼必須符合函數聲明語句規範,很明顯」function「後未包括函數名,這條函數聲明語句明顯不符合規範。瀏覽器
正確的作法:ide
// 以」(「開頭的語句JS並不會將其視做函數聲明 (function(){}).toString(); // 匿名函數 (function(){})() // 匿名函數裝B一點的寫法 void function(){}()
非函數申明代碼不能夠「function」做爲語句開頭,那大括號又是怎麼回事呢。函數
將零個或多個語句聯合在一塊兒,造成一條複合語句,用大括號將其包括
有的文檔上叫「塊語句」,也有人的文檔上叫複合語句,舉個栗子?,咱們能夠這樣寫代碼:ui
{ console.info('輸出一個語句'); console.info('不出錯,是否是很神奇'); };
也就是說若是咱們以大括號開頭,瀏覽器會理解將其視做一個語句塊,語句塊中的代碼和外面的代碼並無本質的區別,也是從上至下而執行。再看個栗子?:
{}; // undefined {a: 'a'}; // 'a'; {a: 'a'}.a; // Uncaught SyntaxError: Unexpected token .
第一行很好理解,沒有任何執行語句,固然輸出undefined
第二行代碼呢,輸出「a」,這裏不要被「:」給矇蔽了,這裏的的冒號是一個標識符,相似於C語言中的標記符,不一樣的是JS中經過「break」與「continue」跳轉到標記符,二C語言中是經過「goto」,關於標記符
第三行代碼等同於:「a: 'a'; .a;」 沒有經過對象主體獲取屬性「a」,因此報錯。
綜上所述,「{}.toString();」 等同於: 「; .toString();」 未經過對象主體調用「toString」方法,不符合JS中期待的表達式
說了這麼多,用語句塊有什麼好處呢,我能想到的惟一好處只有「裝B耍酷」...
JS語句爲何不能以「function」和大括號開頭呢?
MDN 語句
MDN 語句塊
MDN 標記符
MDN Unexpected token
expressions-vs-statements
MDN Expressions_and_Operators