|
|
|
|
|
|
在JavaScript編程中,按照編程習慣,你可能會在每個句末加上一個分號(;),但是我們又發現,現在很多程序根本就不再使用分號了,句末直接為空(什么符號都不寫),并且也不影響程序的正常運行。所以JavaScript加不加分號似乎沒有什么不同。不過如果深入研究,JavaScript加不加分號并不完全相同,在某些情況下,是必須添加分號的。
至于加不加分號關鍵點則需要了解分號對于JavaScript 的影響。

立即函數與分號的關系
下面程序的運行預期為:
a 的值為1請問這段程序運行是否正確?
var a = 1
(function() {
console.log(2)
})()
.
.
.
.
如果你嘗試運行這段程序,則會出現此錯誤:
Uncaught TypeError: 1 is not a function
什么?1 is not a function?我們沒有打算運行數字1,為何要說數字1 不是函數,這種錯誤很難查找到原因,常常會在錯誤的行數上打轉。這個錯誤主要原因是上述程序運行時被視為同一行,概念如下:
var a = 1(function() { /* */ })()因此立即函式的 () 附加在1 上,這是一個調用函數的語法,所以會造成 1 is not a function 的錯誤,如果要避免此錯誤就需要使用分號將其隔開:
var a = 1; // 用分號隔開就對了
(function() {
console.log(2)
})()
return 與分號的關系
再來看一個片段,以下程序中在return 的后方空一行后再回傳值,請問運行結果是什么呢?
function fn() {
return
'小明'
}
console.log(fn())這段程序在 return 后方會被加上一個分號,也因為如此,return 與預期回傳的值被分了開來,所以return 的內容為空值,最終函數也僅能接收到 undefined 的結果。
function fn() {
return;
'小明';
}
console.log(fn()); // undefined所以,分號到底要怎么處理呢?
ASI「Automatic Semicolon Insertion」自動插入分號, 是修正沒有加入分號的片段代碼,但偏偏有些地方沒有發揮其用途(如本篇一開始所介紹到的立即函數),導致程序出現了錯誤;甚至有些程序不會出錯,但會讓你的程序運行結果不如預期。
要解決ASI 的問題,解決方式如下:
不會自動加入分號的規則
以下整理各種「不會」自動加入分號的規則:
1、新的一行是(、[、/開始,這類型通常會直接出現「Uncaught TypeError」導致程序無法運行(其后方的程序也會無法運作)。
var a = 1
var b = a
(a + b).toString()
var a = 1
[1,2,3].forEach(bar)
(function() { })()
(function() { })()
var a = 1
var b = a
/test/.test(b)
2、新的一行以 +、-、*、% 作開始,這類型大多數會影響運算結果,建議合并為一行寫。
var a = 2
var b = a
+a
3、新的一行以,、.作開始,這類型在實戰中很常會運用,主要是避免程序代碼過長所加入的分段,并不會影響運行,多加善用可使程序代碼更易于閱讀。
var a = 2
var b = a
.toString()
console.log(typeof b)
var a = 1
,b = 2 // b 一樣會被 var 聲明
因此,遇到以上的標點符號前方加入分號也是解決辦法。
如果需要加入分號的狀況,除了在語句的末端加入分號外,也可將分號改在「不會自動加入分號」的最前方,如 () 本身不會自動加入分號,當有此需求時可以將 ; 加入至前方以避免錯誤。
// 執行錯誤
(function() { })()
(function() { })()
// 正確
;(function() { })()
;(function() { })()
結論
不加入分號可以讓程序看起來更干凈、精簡(對于習慣加入分號的開發者可能并不這樣認為),且在大部分正確的分段下并不會出現錯誤,僅有少部分的語句會出現執行上的錯誤(很少,大多都可避免),因此許多開發者也會選擇不加入分號。
而加入分號會讓人覺得代碼分段分明,可讀性更強,所以很多人喜歡這樣的寫代碼習慣。
至于選擇何種,只要清楚運行上的限制,其實并無什么不同。
