重學前端學習筆記(二十九)--JavaScript中要不要加分號?

筆記說明

重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,天天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完整的能夠加入winter的專欄學習【原文有winter的語音】,若有侵權請聯繫我,郵箱:kaimo313@foxmail.com。前端

1、自動插入分號規則

1.一、三條規則

  • 要有換行符,且下一個符號是不符合語法的,那麼就嘗試插入分號。
  • 有換行符,且語法中規定此處不能有換行符,那麼就自動插入分號。
  • 源代碼結束處,不能造成完整的腳本或者模塊結構,那麼就自動插入分號。

1.二、例子

//第一行的結尾處有換行符,接下來 void 關鍵字接在 1 以後是不合法的,根據第一條規則,會在 void 前插入換行符。
let a = 1
void function(a){
    console.log(a);
}(a);
複製代碼
// 根據no LineTerminator here 規則, a 的後面就要插入一個分號。
var a = 1, b = 1, c = 1;
a
++
b
++
c
// a ==> 1 b,c ==> 2
複製代碼

1.三、例子 no LineTerminator here 規則展現

UpdateExpression[Yield, Await]:
    LeftHandSideExpression[?Yield, ?Await]
    LeftHandSideExpression[?Yield, ?Await][no LineTerminator here]++
    LeftHandSideExpression[?Yield, ?Await][no LineTerminator here]--
    ++UnaryExpression[?Yield, ?Await]
    --UnaryExpression[?Yield, ?Await]
複製代碼

1.四、IIFE(當即執行的函數表達式)

(function(){
    console.log(1);
})()
(function(){
    console.log(2);
})()

// 不加分號,輸出結果
// 1 Uncaught TypeError: (intermediate value)(...) is not a function

(function(){
    console.log(1);
})();
(function(){
    console.log(2);
})()

// 加分號,輸出結果
// 1 2

// 關於這個問題,遇到過,當時排查幾十分鐘 _(:3」∠)_ , 因爲我以前的是有換行,還有註釋,當時一直不理解,相似下面這樣
(function(){
    console.log(1);
})()

// 處理。。。業務
(function(){
    console.log(2);
})()
複製代碼

1.五、帶換行符的註釋

// 帶換行符的註釋也被認爲是有換行符,return 也有 [no LineTerminator here] 規則的要求,這裏會自動插入分號
function f(){
    return/* This is a return value. */1;
}
f();

// undefined
複製代碼

2、no LineTerminator here 規則

no LineTerminator here 規則表示它所在的結構中的這一位置不能插入換行符。正則表達式

no LineTerminator here 規則

2.一、帶標籤的 continue 語句

// 不能在 continue 後插入換行。
outer:for(var j = 0; j < 10; j++)
    for(var i = 0; i < j; i++)
        continue /*no LineTerminator here*/ outter
複製代碼

2.二、return

function f(){
    return /*no LineTerminator here*/1;
}
複製代碼

2.三、後自增、後自減運算符

i/*no LineTerminator here*/++
i/*no LineTerminator here*/--
複製代碼

2.四、throw 和 Exception 之間

throw/*no LineTerminator here*/new Exception("error")
複製代碼

2.五、async 關鍵字

// 後面都不能插入換行符
async/*no LineTerminator here*/function f(){

}
const f = async/*no LineTerminator here*/x => x*x
複製代碼

2.六、箭頭函數

// 箭頭函數的箭頭前,也不能插入換行
const f = x/*no LineTerminator here*/=> x*x
複製代碼

2.七、yield

// yield 以後,不能插入換行
function *g(){
    var i = 0;
    while(true)
        yield/*no LineTerminator here*/i++;
}
複製代碼

3、不寫分號須要注意的狀況

3.一、以括號開頭的語句

(function(a){
    console.log(a);
})()/* 這裏沒有被自動插入分號 */
(function(a){
    console.log(a);
})()
複製代碼

3.二、以數組開頭的語句

var a = [[]]/* 這裏沒有被自動插入分號 */
[3, 2, 1, 0].forEach(e => console.log(e))
複製代碼

3.三、以正則表達式開頭的語句

// 正則邊除號
var x = 1, g = {test:()=>0}, b = 1/* 這裏沒有被自動插入分號 */
/(a)/g.test("abc")
console.log(RegExp.$1)
複製代碼

3.四、以 Template 開頭的語句

// 沒有自動插入分號,函數 f 被認爲跟 Template 一體的,會被執行。
var f = function(){
  return "";
}
var g = f/* 這裏沒有被自動插入分號 */
`Template`.match(/(a)/);
console.log(RegExp.$1)
複製代碼

我的總結

表示跟winter同樣,也是標分號黨。。。數組

相關文章
相關標籤/搜索