JavaScript 的分號,以及 ASI (Automatic Semicolon Insertion)

目前 community 的主流跟我理出來的期望不一樣... 所以記錄一下。

先提一下背景,在 JavaScript 程式語言裡面,在大多數的情境下是可以省略掉分號 (;) 的,也就是說這兩種寫法都是合法的 JavaScript 語法:

console.log('Hello, world.')
console.log('Hello, world.');

這是因為在 ECMA-262 裡面有 ASI (Automatic Semicolon Insertion) 的設計:「Automatic Semicolon Insertion」。

ASI 設計本身是好的,可以讓開發者少處理 ;,但偏偏 EMCA-262 又允許千變萬化的換行,於是就造成了各種奇怪的現象。

因此早期在 community 上都是推薦無條件加上分號,這可以避免各種奇怪的 bug 與 error,像是「Do you recommend using semicolons after every statement in JavaScript?」以及「Should I use semicolons in JavaScript?」這些問答。

大家會推薦加上分號主要的原因是因為,不加上分號遇到的 error 與 bug 不是那種你知道很雷,所以會主動查詢 & 避開的問題:

而是各種平常寫就會遇到的情況,最容易中獎的是第二組敘述是 ([ 開頭的,像是 ECMA-262 文件裡面提到的 case 就算常見了:

a = b + c
(d + e).print()

// 等價於:
a = b + c(d + e).print();

而且不因為註解受到影響:

// blahblah
a = b + c

// blahblah
(d + e).print()

// 還是等價於:
a = b + c(d + e).print();

另外一個常見的情況是我們會利用 anonymous function 包出一個 block,避免變數污染到外面:

// I want to do blahblahblah...
(() => {
  const a = '';
  // ...
})()

// I want to do another blahblahblah...
(() => {
  const a = '';
  // ...
})()

大多數的情況應該會 error,除非第一個 anonymous function 傳回一個 callable,而這種情況跑出來的結果就更慘了...

另外這種 case 也是常見的情況:

// ...
[1, 2, 3].forEach(...)

// ...
[4, 5, 6].forEach(...)

// 等價於:
[1, 2, 3].forEach(...)[4, 5, 6].forEach(...)

這邊省略分號最大的問題是你無法知道「自己這行需不需要加上分號」,因為註解可能很長有個 30 行,所以依照這些現況,比較好的方法應該是全部加上分號,保持一致性。

但這幾年所有的 frontend framework 都是推動拿掉分號,這可以從各家的文件看到,就搞不懂 community 是怎麼推導出來的... 在全部都拿掉分號的情況下,遇到上面的情況就得寫成不一致的 style:

// ...
[1, 2, 3].forEach(...);

// ...
[4, 5, 6].forEach(...)

查了目前可行的 workaround,大多都是透過 ESLint 類的工具來擋可能會出現 bug 的地方,也只能先這樣做了...

GitHub 對 Open Source Community 請願的回應

大約一個多月前 (2016 年一月 15 日),一群用 GitHub 發展 Open Source 軟體的人對 GitHub 提出請願,要求重視 Open Source Community 在 GitHub 平台上遇到的問題:「An open letter to GitHub from the maintainers of open source projects」。

這個請願在卡了將近一個月後,陸陸續續有相當多要搬出 GitHub 的討論,像是 eslint 就直接在 GitHub 開了 issue,討論搬出 GitHub 會遇到的問題以及可能的解決方法:「Investigate switching away from GitHub」。

在二月 13 日的時候,GitHub 透過 pull request 發出回應說「我們在處理了」,但也沒講正在處理什麼,看起來就是個很 PR 的回應:「Dear Open Source Maintainers」。

直到昨天,三個主要的請願中關於 issue 範本的問題 (也就是下面這段) 總算有進展了:

Issues are often filed missing crucial information like reproduction steps or version tested. We’d like issues to gain custom fields, along with a mechanism (such as a mandatory issue template, perhaps powered by a newissue.md in root as a likely-simple solution) for ensuring they are filled out in every issue.

為了解決使用者在開 issue 時有時會忘記給出完整的環境資訊 (以及其他有用的資料),GitHub 推出了新的功能,在開 issue 或 pull request 時利用 template 讓使用者有個範本可以照著填寫,同時 template 也支援 Markdown,讓填寫的方式會更豐富一些:「Issue and Pull Request templates」。

這總算開始有進展了。但也開始感覺到 GitHub 的動作已經開始慢下來了...