用空格還是用 Tab 鍵?Google 推出《JavaScript 指南》解答程式白痴問題!

評論
評論

本篇來自合作媒體 36kr,原文來自 Medium 標題「google publishes a javascript style guide here are some key lessons」。

Google 的工程師大大為了幫助剛入手 JavaScript 者寫出乾淨、易懂的 code,提供了一個獨具特色的教學《JavaScript 指南》,而本文作者丹尼爾西蒙斯,一位 web 開發人員/Java 愛好者精心總結了 Google 推出的這份指南中最有趣、最有用的十三條規則。

JS 具有強大的靈活性和包容性,因此,JS 的編寫具有不同的風格,因此如何保證你的原始碼在編寫過程中保持著統一的風格才是編寫 JS 的過程中需要注意的。

Google 和 Airbnb 使用著兩種最流行的編寫規則,它們對細節的把關深深的影響著我,從一個個的標點到頁面的佈局,扣著一個個的小細節,這也深深的影響了我在寫 JS 過程中的一些習慣。以下是我挑選的 Google JS 指南中最有趣、有用的十三條規則。

我將針對每一個規則都會給一個總體的敘述,然後再進行詳細的敘述,結合自身的開發經歷,給出一些實用的介紹,如果條件允許,還有一些相關的例子給大家分享一下。

用空格還是用 Tab 鍵?

除了行終止符之外,ASCII 字符 (0x20) 是在原始檔案中出現的唯一空白字符。這意味著 Tab 鍵不用於縮排。

因此,你應該使用空格來實現你的設計而不是 Tab 鍵,而且只要鍵入兩個空格就可以,而不是四個空格。

// bad
function foo() {
∙∙∙∙let name;
}

// bad
function bar() {
∙let name;
}

// good
function baz() {
∙∙let name;
}

必不可少的分號

每個語句都必須以分號結束。不要為了省事使用自動分號插入。那會給你帶來後面很多不必要的麻煩的。

// bad
let luke = {}
let leia = {}
[luke, leia].forEach(jedi => jedi.father = 'vader')
// good
let luke = {};
let leia = {};
[luke, leia].forEach((jedi) => {
  jedi.father = 'vader';
});

雖然我無法想像為什麼有人反對這個想法,但在 JS 中使用分號正在成為一種新的「空格與 Tab 鍵」的爭論。Google 是支援使用分號的,至於剛入行的還是建議跟著潮流走。

不要使用 ES6 模板

不要使用 ES6 模塊 (即導出和輸入關鍵字),因為它們的語義還沒有最終確定。

// Don't do this kind of thing yet:
<em class="markup--em markup--pre-em">//------ lib.js ------</em> export function square(x) { return x * x; } export function diag(x, y) { return sqrt(square(x) + square(y)); } <em class="markup--em markup--pre-em">//------ main.js ------</em> import { square, diag } from 'lib';

中立態度的水平對齊

在 Google 提供的模板裡面,水平對齊並沒有提出很高的要求,還是比較隨意的。

水平對齊就是在目標模塊的周邊增加可變量的額外空格,使得目標出現在我們想讓他出現的位置上就可以。

// bad
{
  tiny:   42,  
  longer: 435, 
};
// good
{
  tiny: 42, 
  longer: 435,
};

不要使用 var 關鍵字

除非需要重新分配一個變量,否則將所有本地變量聲明為 const 關鍵字或 let 型。默認情況下使用 const。但是在使用 var 關鍵字的時候一定要慎重。

其實在平時學習中,我仍然看到人們在 StackOverflow 和其他地方的 code 示例中使用 var 型。我不知道其他人使用 var 是因為什麼,可能這只是一種老習慣垂死掙扎吧。

首選箭頭

個人感覺箭頭函數已經提供了簡潔的語法,並解決了許多困難。所以個人更喜歡箭頭函數而不是函數關鍵字,特別是巢狀函數。

說實話,我認為箭頭不僅功能很好,而且它們更簡潔,更美觀。而且,事實證明,它們也有很重要的作用。、

// bad
[1, 2, 3].map(function (x) {
  const y = x + 1;
  return x * y;
});

// good
[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});

使用模板字串而不是連接

在復雜的字符串連接上使用模板字串,特別是在涉及多個字串時。因為模板字串可以跨越多個行。

// bad
function sayHi(name) {
  return 'How are you, ' + name + '?';
}

// bad
function sayHi(name) {
  return ['How are you, ', name, '?'].join();
}

// bad
function sayHi(name) {
  return `How are you, ${ name }?`;
}

// good
function sayHi(name) {
  return `How are you, ${name}?`;
}

 

不要對長字符串使用斷行

在普通或模板字符串中不要使用行延續 (也就是說,在字符串結尾以反斜杠結束一行字)。儘管 ES5 允許這樣做,但如果在斜杠之後出現任何尾隨空格,那麼它就會導致棘手的錯誤,而且對新手來說不太明顯。

// bad (sorry, this doesn't show up well on mobile)
const longString = 'This is a very long string that \
    far exceeds the 80 column limit. It unfortunately \
    contains long stretches of spaces due to how the \
    continued lines are indented.';
// good
const longString = 'This is a very long string that ' + 
    'far exceeds the 80 column limit. It does not contain ' + 
    'long stretches of spaces since the concatenated ' +
    'strings are cleaner.';

有趣的是,這是 Google 和 Airbnb 意見不同的規則 ( 這是 Airbnb 的規範 )。雖然 Google 推薦連接更長的字符串 (如下所示),但 Airbnb 的風格指南建議基本上什麼都不做,並且允許長字符串在需要的時候繼續使用。

// bad (sorry, this doesn't show up well on mobile)
const longString = 'This is a very long string that \
    far exceeds the 80 column limit. It unfortunately \
    contains long stretches of spaces due to how the \
    continued lines are indented.';
// good
const longString = 'This is a very long string that ' + 
    'far exceeds the 80 column limit. It does not contain ' + 
    'long stretches of spaces since the concatenated ' +
    'strings are cleaner.';

“for…of”是“for 循環”的首選類型

在 ES6 中,語言現在有三種不同的 for 循環。工程師是可以使用所有的循環,但在可能的情況下應該首選 for-of 循環。

我個人感覺 for 更適合於對象,而 for of 更適合於數組。只是適合不同的風格。雖然 Google 的規範並不一定與這個想法相矛盾,但是,可以看出 Google 對於這個迴圈還是情有獨鍾的。

不要使用 eval()

不要使用 eval 或函數 (…string) 構造函數 (程式碼載入器除外)。這些特性可能是危險的,在 CSP 環境中根本不起作用。

eval() 的 MDN 頁面甚至有一個部分叫做「不要使用 eval!」的提示。

// bad
let obj = { a: 20, b: 30 };
let propName = getPropName();  // returns "a" or "b"
eval( 'var result = obj.' + propName );
// good
let obj = { a: 20, b: 30 };
let propName = getPropName();  // returns "a" or "b"
let result = obj[ propName ];  //  obj[ "a" ] is the same as obj.a

常數應該以全部大寫命名,並且以底線分隔。

常數名稱使用類似於 CONSTANT_CASE 的表示方法: 所有大寫字母,用底線隔開。

如果可以絕對確定變量不改變,就可以使用常數來定義,這樣也可以表示某個變量在整個過程中不會發生改變。

這個規則的一個特例就是,如果這個變量是函數特有的話,最好是申名在函數的空間裡面。

每個變量獨立對待

這沒有什麼好介紹的,直接上 code:

// bad
const number = 5;
// good
const NUMBER = 5;

特別注意使用單引號,而不是雙引號

普通的字符串是用單引號 (‘) 來分隔的,而不是雙引號 (")。

提示: 如果字符串包含單引號字符,請考慮使用模板字符串,以避免誤導。

// bad
let a = 1, b = 2, c = 3;
// good
let a = 1;
let b = 2;
let c = 3;

 

最後的總結

正如我一開始所說的,這些不是唯一的標準。Google 只是眾多科技巨頭中的一個,而這些只是眾多工程師總結出來的經驗而已。

看看 Google 這樣的公司提出的風格建議還是比較有意義的,它僱傭了很多聰明的人,他們花了大量時間研究如何編寫優秀的代碼。

如果你想遵循「Google 相容的開源碼」的指導方針,你可以遵循這些規則——但是,你要是有自己的喜好,那很棒,你可以自由地放飛自我。

我個人認為,在很多情況下,Airbnb 的規範比 Google 更有吸引力。不過無論對這些特定的規則採取何種立場,我們在編寫任何類型的代碼時,唯一的要求就是要保持風格上的一致性。

相關文章

評論

知名廠商強力徵才中