JavaScript排版陷阱 – return的分號地雷
| | 1 | | ![]() |
印象中,JavaScript跟C、C#一樣,可以在程式碼段落中任意插入空白、換行而維持相同語意,屬於Free-Form Language的一員。
雖然排成這樣沒什麼道理,但以下JavaScript可以執行無誤:
function calc(a, b) {
var c = (a
+ b
) / 2
;
return c;
}
alert(calc(5, 4));
手邊有段程式,在完成初步測試後花了點時間重新檢視程式碼,進行一些調整美化,在某個function中,由於return傳回的字串有點長,為了讓排版更好看一些,我改成以下寫法:
function getSomething() {
// ... blah blah ...
return
"line1 blah blah blah blah blah" +
"line2 blah blah blah blah blah" +
"line3 blah blah blah blah blah";
}
改完後重新測試程式,晴天霹靂! 原本可以跑的程式壞掉了!!
由於這波程式微調的地方不少,花了好些時間才抓出問題出在原本return "line1 blah..."被改成return接換行,下一行才放"line1 blah..."。
經過研究,得知這個雷人陷阱有個專業術語叫Automatic Semicolon Insertion (ASI),JavaScript引擎會自動在以下指令後方加上分號";": [參考]
- empty statement
var
statement- expression statement
do-while
statementcontinue
statementbreak
statementreturn
statementthrow
statement
ASI跟return結合在一起,最為惡名昭彰、傷人無數... 網路上可以找到很多相關文章。簡單來說,前述的doSomething會程式會被解析成:
function getSomething() {
// ... blah blah ...
return;
"line1 blah blah blah blah blah" +
"line2 blah blah blah blah blah" +
"line3 blah blah blah blah blah";
}
於是doSomething()傳回undefined,導致不正常的結果。
而ASI的特性,只有JavaScript有,return後方換行再寫,在C#、C、Java上都不會有問題,無怪乎許多程式老鳥也會中箭,在調整JavaScript程式碼排版時,宜多加留意!
Comments
# by Huang47
建議跑 linter, jslint or jshint