[翻譯] Google的javascript風格指南中值得注意的13點

寫在文章前

這篇文章翻譯自13 Noteworthy Points from Google’s JavaScript Style Guide . 若是以爲風格指南的完整版太長的話,這篇文章提取出來了比較值得注意的幾點,好比說tab vs space這種堪比鹹甜豆腐腦的戰爭。(還記得美劇硅谷中,Richard就由於是堅決地‘tab鍵’黨跟女朋友分了手。文章翻譯的很差的地方還望指出和多多包涵。javascript

Google的javascript風格指南中值得注意的13點

衆所周知,GOOGLE推出了一個針對如何寫JavaScript的風格指南,這個指南被認爲(Google 本身認爲)是可以寫出整潔,易理解代碼的最佳風格化實踐。html

這些不是針對如何編寫嚴謹的JavaScript代碼的那種嚴格和快速的規則, 僅僅只是一些爲了保持原文件中一致,和保證吸引人的風格選擇而提出的一些禁止行爲。這對於JavaScript來講是格外有趣的,由於JavaScript是一個靈活的,「寬容的」語言,它老是容許普遍的不一樣的風格化選擇。java

Google 和 Airbnb 擁有兩種最流行的風格指南。我強烈的建議大家兩套指南都去看一看,若是你花大量時間寫JS代碼。git

下面的十三條是我認爲在Google Js 風格指南中最有趣和最相關的規則。程序員

這些規則處理了那些引發人們激烈競爭的問題(好比說tab vs 空格鍵, 如何使用分號的爭議),以及更多的處理了一些模糊的規則,這讓我很驚喜。他們無疑會改變我之後寫個人js代碼的方式。es6

對於每個規則, 我會寫一個規則總結,跟着一個在風格指南中詳細描述這條規則的支持引用的後面。若是可行,我也會提供一個這種書寫風格在實際中的例子,並把它與不聽從這種規則的代碼進行對比。github

使用空格,而不是tab鍵

Aside from the line terminator sequence, the ASCII horizontal space character (0x20) is the only whitespace character that appears anywhere in a source file. This implies that… Tab characters are not used for indentation.數組

除行終結符外,ASCII水平空格字符(0x20)是出如今源文件中各處的惟一的空白格字符,這代表......(此處省略)......Tab字符不該該被用於縮進bash

這條指南指出你應該使用兩個空白格(而不是四個)來縮進。app

//譯者注:'.'表明空格
//bad
function foo(){
....let name;
}

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

//good
function baz(){
..let name;
}
複製代碼

分號應該加

Every statement must be terminated with a semicolon. Relying on automatic semicolon insertion is forbidden. 每個聲明必需要以分號結尾。嚴禁徹底依賴自動分號注入機制;

儘管我不可思議爲何每一個都反對這個想法,但在js中貫徹分號的使用已經變成了新的‘空格 vs tab’鬥爭。 Google在這裏堅決的站在了‘保分派’。

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

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

不要使用ES6模塊( 以目前的情況來看)

Do not use ES6 modules yet (i.e. the export and import keywords), as their semantics are not yet finalized. Note that this policy will be revisited once the semantics are fully-standard. 目前,不要使用ES6 模塊(例如,關鍵字export和import相關),由於他們的語義並沒被完善,注意,一旦es6的語義被徹底標準化,這條政策就會被從新審查。

//不要寫下面這種作法
// ------- lib.js -------
export function square(x){
return x*x;
}
export function diag(x,y){
return sqrt(square(x)+square(y));
}
//main.js
import {square,diag} from 'lib';
複製代碼

不建議使用水平對齊(但不由止)

This practice is permitted, but it is generally discouraged by Google Style. It is not even required to maintain horizontal alignment in places where it was already used. 水平對齊這種作法是容許的,但他不是Google風格所提倡的。在那些已經用到水平對齊的地方,甚至不須要繼續維持水平對齊。

水平對齊是一種在你的代碼中增長許多不一樣數量的額外空格的作法,目的是爲了讓某種符號直接出如今以前的某些行的某些符號下方。

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

//good
{
    tiny: 42,
    longer: 435,
}
複製代碼

不要再使用var關鍵字了

Declare all local variables with either const or let. Use const by default, unless a variable needs to be reassigned. The var keyword must not be used. 使用const或者let 來聲明全部的局部變量。默認狀況下使用const關鍵字,除非須要從新分配一個變量。var 關鍵字請不要使用。

我仍舊在StackOverFlow或者其餘地方的代碼片斷中看到某些人還在使用var。我不能肯定是否這些人在真正的代碼中會轉化成const或者換var,仍是這只是一些很難徹底改掉的舊習慣。

// bad 
var example = 42;
// good
let example = 42;
複製代碼

優先使用箭頭函數

箭頭函數提供給咱們一種簡潔的語法而且修復了許多因爲this指針致使麻煩。優先在函數關鍵字中使用箭頭函數,尤爲是那些嵌套函數。

說實話,我只是由於箭頭函數更簡潔和看起來更好看而以爲箭頭函數很好。事實上,他們提供了一個更重要的理由去使用箭頭函數。

//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;
})
複製代碼

使用模板字符串來代替數組合並

Use template strings (delimited with `)over complex string concatenation, particularly if multiple string literals are involved. Template strings may span multiple lines. 使用模板字符串來進行復雜字符串的鏈接(用 ` 分割),尤爲是有大量字符串文字的狀況。模板字符串能夠跨越多行。

//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}?`;
}
複製代碼

不要對長字符串使用續行符號

Do not use line continuations (that is, ending a line inside a string literal with a backslash) in either ordinary or template string literals. Even though ES5 allows this, it can lead to tricky errors if any trailing whitespace comes after the slash, and is less obvious to readers. 不管在普通字符串或者模板字符串中都不要使用續行符(續行符就是使用反斜槓的字符串結束一行)。 儘管ES5容許這麼作,可是若是在反斜槓以後有空格尾隨就會致使很是意料以外的錯誤,而且對於閱讀的人來講不明顯。

很是有趣的是,有關於這一條,Google和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 colomn 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循環的首選類型

With ES6, the language now has three different kinds of for loops. All may be used, though for-of loops should be preferred when possible. 在ES6中,JS語言如今有三種不一樣種類的for循環。三種都能被使用,可是for-of循環在可使用的時候應該被優先選擇。

若是你問個人話,我會以爲這條很奇怪,但我認爲,我應該把這條涵蓋進來由於google聲明瞭一種喜好的for循環形式是十分有趣的。

在我看來,for...in循環更適合遍歷object對象,而for..of循環更適合數組。畢竟殺雞焉用宰牛刀?

雖然Google對於這條的聲明並無徹底反駁個人觀點,可是知道他們對於for循環的偏好依舊是一件很是有趣的事情。

不要使用eval()##

Do not use eval or the Function(...string) constructor (except for code loaders). These features are potentially dangerous and simply do not work in CSP environments. 不要使用eval 或者 Function(...string) 構造器(除非是代碼加載器)。這些特色是一些潛在的危險,而且很容易在CSP環境中沒法運行。

MDN 官網對於eval()甚至有一個小節叫作'不要使用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"] 和obj.a是同樣
複製代碼

常量應該被以全大寫的方式並使用下劃線分隔得方式命名(ALL_UPPERCASE)

Constant names use CONSTANT_CASE: all uppercase letters, with words separated by underscores. 常量應該使用常量格式(CONSTANT_CASE): 所有使用大寫字母,並使用下劃線進行單詞分隔。

若是你十分的肯定一個變量不會被改變,那你應該以全大寫名字的方式聲明這個常量。這會使常量的不變性更明顯的貫徹在你的代碼中。

一個須要注意的使用這個規則例外就是若是常量是函數做用域內的狀況。在這種狀況下,常量要被寫爲駝峯式。

// bad
const number = 5;
// good
const NUMBER = 5;
複製代碼

一個聲明, 一個變量

Every local variable declaration declares only one variable: declarations such as let a = 1, b = 2; are not used. 一個局部變量只聲明一個變量:形如 let a = 1 , b = 2 這種聲明方式不該被使用。

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

//good
let a = 1;
let b = 2;
let c = 3;
複製代碼

使用單引號,不要使用雙引號

Ordinary string literals are delimited with single quotes ('), rather than double quotes ("). 普通的字符串使用單引號(')分隔,不建議使用雙引號(").

建議: 若是一個字符串中包括單引號字符,使用模板字符串來避免轉義引號。

//bad
let directive = "No identification of self or mission."

//bad
let saying = 'say it ain\u0027t so.'

//good
let directive = 'No identification of self or mission.'

//good
let saying = `Say it ain't so`; 複製代碼

結語

就像我在一開始說的那樣,這些規定不是強制要求的。Google只是衆巨頭之一,而上面這些只是一些建議而已。

能夠說,看到像google這樣擁有衆多寫得出優秀代碼的優秀程序員的大公司推出了這樣一套樣式建議是十分有趣的。

若是你想寫出‘google 兼容的源碼’,你能夠聽從這些規則,可是,顯然,有不少人並不一樣意這些規則。已徹底能夠隨心所欲的違反一個甚至全部的規定。

我我的認爲,airbnb的規定比Google的更吸引人。但不管你對這些規定採起什麼態度和立場,重要的是要時刻保持代碼樣式風格的一致性。

譯者結語

在原文做者的評論中,我我的以爲有一個評論特別有道理。這種樣式風格其實針對團隊更多一些。由於我的的習慣基本不會有太大的變化,很不容易在代碼中存在風格不一致,可是當團隊完成工做的時候,很容易會出現風格衝突的問題。這樣的代碼不利於維護和閱讀,有的時候可能還會有更糟的狀況好比變量污染等問題。 所以制定一個規範能夠很好的解決問題,不管聽從的google的,airbnb的或者你所在的團隊本身的。

相關文章
相關標籤/搜索