介紹
犀牛書第二章主要敘述了一下 JavaScript 的 詞法結構,其實就是 語法結構。
主要需要注意下 換行、分號的自動填補規則,知道了引擎的解析規則後就可以避免因為省略了必要的分號而導致奇怪的 bug。
自我提問
- 什麼情況下必須要填補分號?
var a = 1, b = 2, c = 3 a = b + c (b + c).toString() 複製程式碼
function foo() { return 123 } console.log(foo()); 複製程式碼
腦圖
關鍵知識點
字符集
JavaScript 中使用的是 Unicode 字符集,並且 區分大小寫。
var abc = 1;
var ABC = 2;
// 1 2
console.log(abc, ABC);
複製程式碼
換行符
換行符有時會被忽略,可能會導致不必要的 bug,具體見下方省略分號的意外bug。
分號自動填補規則
分號自動填補的規則是:在缺少分號會報錯(語法上)時自動在換行初填補分號。
var // 銜接下一行不報錯 ===> var a
a // 銜接下一行報錯,自動填補分號 ===> var a;
a // 銜接下一行不報錯 a =
= // 銜接下一行不報錯 a = 1
1 // 銜接下一行報錯,自動填補分號 ===> a = 1;
console.log // 銜接下一行不報錯 ===> console.log(a)
(a)
複製程式碼
上述程式碼等價於
var a; a = 1; console.log(a);
複製程式碼
自動填補規則的特例
自動填補規則有 兩個例外情況:
- 遇到 return、break、continue 時後面的換行會 自動填補分號
- 遇到 ++ 或 -- 運算子時,會 將運算子作為字首
function foo() {
return // 遇到 return 直接補全分號
123
}
// undefined
console.log(foo());
複製程式碼
上述程式碼等價於
function foo() {
return;
123
}
console.log(foo());
複製程式碼
var a = 1, b = 2;
a // 下面是 ++ 運算子,放棄銜接,填補分號 ===> a;
++ // 銜接 ===> ++b
b // 銜接失敗,填補分號 ===> ++b;
// 1 3
console.log(a, b);
複製程式碼
上述程式碼等價於
var a = 1, b = 2;
a;
++b;
console.log(a, b);
複製程式碼
var a = 1, b = 2;
a
++ // 這裡會直接報錯
console.log(a, b);
複製程式碼
省略分號的意外bug
某些情況下省略分號會導致意料之外的 bug。
var a = 1, b = 2, c = 3;
a = b + c // 這裡會將嘗試銜接下一句 ===> a = b + c(b+c).toString(),語法解析上沒有問題,但是卻不是編寫者的本意,從而導致了意料之外的結果
(b + c).toString()
複製程式碼
分號風格抉擇
是否需要在所有地方都填補分號是個風格問題 沒有孰優孰劣,這個問題一般 靠團隊程式碼風格的統一,或者 一些程式碼的格式化工具 就可以 很好的解決(比如 prettier)。
不過實質上而言加上分號比不加分號在編譯效能上會有所優勢,因為不加分號會讓 JavaScript 一直猜測什麼時候需要填補分號,但是在現在都用 babel 等預編譯程式碼的情況下並沒什麼區別。