拯救一切強迫症 讀《編寫可維護的 JavaScript》(一) 本文寫於 2020 年 4 月 24 日 我在小學的時候就有接觸過編程,所以讀大一的時候 C 語言還算是輕車熟路。自然會有很多同學給我看他們的代碼,麻煩我幫助他們找一找 bug。 我代碼拿到手的第一件事兒是啥? 重排代碼格式!(相信大家 ...
拯救一切強迫症 - 讀《編寫可維護的 JavaScript》(一)
本文寫於 2020 年 4 月 24 日
我在小學的時候就有接觸過編程,所以讀大一的時候 C 語言還算是輕車熟路。自然會有很多同學給我看他們的代碼,麻煩我幫助他們找一找 bug。
我代碼拿到手的第一件事兒是啥?
重排代碼格式!(相信大家基本上大學學 C 語言都用的是 VC++,並沒有代碼自動格式化功能,現在我極力推薦 prettier 進行自動格式化)
通常我看到的代碼都是這樣的:
if (wl && wl.length) {
for (i = 0, l = wl.length; i < l; ++i) {
p = wl[i]
type = Y.Lang.type(r[p])
if (s.hasOwnProperty(p)) {if (merge && type == 'object') {
Y.mix(r[p], s[p])
} else if (ov || !pinr) {
r[p] = s[p]
}
}
}
}
這種代碼人類幾乎沒有辦法讀懂!
老話說得好:代碼是給人讀的,只是偶爾給機器看一下。
讓我們來重置一下縮進:
if(wl && wl.length){
for(i=0, l=wl.length; i < l; ++i) {
p = wl[i];
type = Y.Lang.type(r[p]);
if(s.hasOwnProperty(p)){
if(merge && type == 'object'){
Y.mix(r[p], s[p]);
} else if (ov || !(pinr)){
r[p] = s[p];
}
}
}
}
代碼瞬間變得易於閱讀了!
01 縮進
接下來我們來看一看書中對於縮進的觀點。
使用製表符縮進
每一個縮進層級都代表一個單獨的製表符。也就是一個製表符一個縮進,兩個製表符兩個縮進,以此類推。
他的好處在於,編輯器可以直接修改製表符的長度,可長可短,隨心所欲。
但是缺點在於系統對於製表符的解釋不一樣。我們在 windows、macOS、Linux 中看到的製表符可能都不一樣。
使用空格縮進
有幾種做法:2 個空格表示一個縮進、4 個空格表示一個縮進、8 個空格表示一個縮進。
很多團隊經常會選擇 4 個空格,因為這是一種折中的方案。
在文本編輯器中,我們可以配置在敲擊 tab 時,自動插入 n 個空格,這樣,不管在哪裡打開,代碼都會是一樣的。
我們看一些著名團隊的選擇——
製表符:
- jQuery
- Dojo
空格:
- Dauglas Crockford 使用 4 個空格字元的縮進;
- Sprout Core 使用 2 個空格的縮進;
- Goolge 的 JavaScript 使用 2 個空格的縮進。
作者個人推薦使用四個空格作為一個縮進層級。
無論如何,選擇了其中一種,就一直用下去,千萬不要在一個文件里混用!
02 語句結尾
作者認為應該加分號,但是我個人不喜歡加分號。
JS 又一個叫做 Automatic Semicolon Insertion 機制,叫做自動分號插入機制。但是 ASI 的規則非常非常的複雜,所以我們很難預料他會在哪裡插入分號,包括 jQuery、Google、Dojo 都是推薦使用分號結尾。
03 一行的長度
很多很多的編程規範提到過,一行長度不宜超過 80。
這個規則是因為當年的文本編輯器,單行字數限制就是 80。
但是現在,即使我們的屏幕寬了、解析度高了,還是推薦大家使用 80 的長度限制。
看看大公司的規範:
- Java 語言編程規範,80;
- Android 開發者編碼風格指南,80;
- 非官方的 Ruby 編程規範:80;
- python,79。
在超過了 80 的長度之後就需要換行了,比如這樣:
callAFunction(document, element, window, "somestringvalue", true, 123,
navigator);
在換行後應該追加一個縮進
要註意,不要讓運算符或者逗號換行了:
callAFunction(document, element, window, "somestringvalue", true, 123
, navigator);
04 空行
為了保證代碼的可讀性,我們會適當的空上幾行。
if(wl&&wl.length){
for(i = 0, l = wl.length; i<l; ++i) {
p = wl[i];
type = Y.Lang.type(r[p]);
if(s.hasOwnProperty(p)){
if(merge&&type=='object') {
Y.mix(r[p],s[p]);
} else if (ov || !(pinr)) {
r[p]=s[p];
}
}
}
}
if (wl && wl.length) {
for (i = 0, l = wl.length; i < l; ++i) {
p = wl[i]
type = Y.Lang.type(r[p])
if (s.hasOwnProperty(p)) {
if (merge && type == 'object') {
Y.mix(r[p], s[p])
} else if (ov || !pinr) {
r[p] = s[p]
}
}
}
}
(未完待續)