javascript weird part (32) – 觀念小叮嚀 語法解析器

我們要再一次熟悉語法解析器,因為這對後面認識底層知識十分重要。

已經知道我們寫的程式碼不會直接被電腦執行,而是有一個在程式碼和電腦中間中介的程式,轉換你的程式為電腦懂的東西。這就是瀏覽器裡的 JavaScript 引擎做的事情,其中之一就是語法解析器。

語法解析器會閱讀程式碼,判斷這是否有效。如果它一個一個字看程式碼,看到 ‘r’,它假設你可能要輸入的是 ‘return’,所以它會預期再看到一個 ‘e’,它會一個一個字進行。如果它看到一些非預期的東西,它會認為是錯誤。但如果它看到的是預期的有效語法,它會繼續下去,它知道你意圖要做什麼。它會在遇到分號的時候結束

所以語法解析器會做假設、遵守某些規則,甚至可以在執行前改變你的程式碼,這就是發生在 JavaScript 的狀況。

認識 JavaScript 引擎如何閱讀程式碼很重要:逐字地、採用一些規則、判斷語法有效性、決定你要做什麼.這些就是在程式碼執行前發生的事情。所以它可能採取某些改變。

儘管語法解析器是幫助我們的工具,但是在使用 JavaScript 的時候,一定要避免一個和語法解析器有關的危險狀況:自動插入分號 (Automatic semocolon insertion)。

分號在 JavaScript 核心不是必要的,這是因為 JavaScript 引擎自動完成某些事情。它一次看一個字母,一個特定程式句,它會知道程式語言應該呈現什麼樣子,例如輸入一個 return 但沒有輸入 ; 就按 enter 鍵,這時按下的 enter 就會是一個 carriage return,這是一個雖然看不見但存在的字元
語法解析器認識它,所以會拒絕在解析器沒有分號的時候就跳倒下一行,解析器不允許使用這個特別的陳述句,所以解析器會自動插入分號。語法解析器會在預期你有分號的地方,自動幫你補上分號

雖然這是很棒的事情,但永遠要記得要自己打出分號,因為我們會想要 JavaScript 引擎幫我們下決定,這才能確定程式碼是我們要的樣子。尤其在回傳的時候,自動插入分號會導致很大的問題

1
2
3
4
5
6
7
function getPerson(){
return
{firstname: 'Tony'
}
}

console.log(getPerson());

如果語法解析器在 return後面發現 carrige return (按下enter)
,它會自動插入分號,所以出現 undefined。所以它離開這個函數了

要解決這個問題,就要告訴語法解析器我們正在做什麼,要預防自動插入分號
,就用空格加一個大括號,解析器才知道我們開始用物件實體語法

1
2
3
4
5
6
7
function getPerson(){
return {
firstname: 'Tony'
}
}

console.log

雖然不是每次必要把大括號放在跟函數、for 迴圈、if 陳述句同一行。但這樣做可以避免自動插入分號,避免這個難以追蹤的危險。