原文地址: https://medium.freecodecamp.org/google-publishes-a-javascript-style-guide-here-are-some-key-lessons-1810b8ad050b
做者: Daniel Simmons
摘要:本文總結了Google發佈的JavaScript代碼規範中比較重要的部分,適合想要養成良好代碼規範的讀者借鑑。
Google爲了那些還不熟悉代碼規範的人發佈了一個JS代碼規範。其中列出了編寫簡潔易懂的代碼所應該作的最佳實踐。javascript
代碼規範並非一種編寫正確JavaScript代碼的規則,而是爲了保持源代碼編寫模式一致的一種選擇。對於JavaScript語言尤爲如此,由於它靈活而且約束較少,容許開發者使用許多不一樣的編碼樣式。html
Google和Airbnb各自佔據着當前最流行的編碼規範的半壁江山。若是你會在編寫JS代碼上投入很長時間的話,我強烈推薦你通讀一遍這兩家公司的編碼規範。java
接下來要寫的是我我的認爲在Google的代碼規範中,與平常開發密切相關的十三條規則。git
它們處理的問題都很是具備爭議性,包括tab與空格、是否強制使用分號等等。還有一些令我感到驚訝的規則,每每最後都改變了我編寫JS代碼的習慣。程序員
對於每一條規則,我都會先給出規範的摘要,而後引用規範中的詳細說明。我還會舉一些適當的反例論證遵照這些規則的重要性。github
除了每一行的終止符序列,ASCII水平空格符(0x20)是惟一一個能夠出如今源文件中任意位置的空格字符。這也意味着,tab字符不該該被使用,以及被用來控制縮進。
規範隨後指出應該使用2個,而不是4個空格帶實現縮進。segmentfault
// bad function foo() { ∙∙∙∙let name; } // bad function bar() { ∙let name; } // good function baz() { ∙∙let name; }
每一個語句必須以分號結尾。不容許依賴於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模塊的語義尚不徹底肯定,因此暫時不要使用,好比export和import關鍵字。一旦它們的相關規範制定完成,那麼請忽略這一條規則。
// 暫時不要編寫下面的代碼: //------ 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';
譯者注:感受遵照這條規範不大現實,畢竟如今已經有babel了。並且使用React時,最佳實踐就是使用ES6模塊吧。
Google的代碼規範容許但不推薦對代碼進行水平對齊。即便以前的代碼中作了水平對齊的處理,之後也應該避免這種行爲。
對代碼進行水平對齊會在代碼中添加若干多餘的空格,這讓相鄰兩行的字符看上去處於一條垂直線上。babel
// bad { tiny: 42, longer: 435, }; // good { tiny: 42, longer: 435, };
使用const或let來聲明全部局部變量。若是變量不須要被從新賦值,默認應該使用const。應該拒絕使用關鍵字var。
我不知道是由於沒有人能說服他們,仍是說由於舊習難改。目前我仍能看到許多人在StackOverFlow或其餘地方使用var聲明變量。less
// bad var example = 42; // good const example = 42;
箭頭函數提供了一種簡潔的語法,而且避免了一些關於this指向的問題。相比較與function關鍵字,開發者應該優先使用箭頭函數來聲明函數,尤爲是聲明嵌套函數。
坦白說,我曾覺得箭頭函數的做用只在於簡潔美觀。但如今我發現原來它們還有更重要的做用。
// 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}?`; }
在JS中,\
也表明着續行符。Google的代碼規範不容許在不論是模板字符串仍是普通字符串中使用續行符。儘管ES5中容許這麼作,但若是在\
後跟着某些結束空白符,這種行爲會致使一些錯誤,而這些錯誤在審閱代碼時很難注意到。
這條規則頗有趣,由於Airbnb的規範中有一條與之不相同的規則
Google推薦下面這樣的寫法,而Airbnb則認爲應該順其天然,不作特殊處理,該多長就多長。
// bad (建議在PC端閱讀) 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
在ES6中,有3種不一樣的for循環。儘管每一種有它的應用場景,但Google仍推薦使用
for...of
。
真有趣,Google竟然會特別指定一種for循環。雖然這很奇怪,但不影響我接受這一觀點。
之前我認爲for...in
適合遍歷Object,而for...of
適合遍歷數組。由於我喜歡這種各司其職的使用方式。
儘管Google的規範與這種使用方式相沖突,但Google對for...of
的偏心依然讓我以爲十分有趣。
除非是在code loader中,不然不用使用eval或是Function(...string)結構。這個功能具備潛在的危險性,而且在CSP環境中沒法起做用。
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
常量命名應該使用全大寫格式,並用下劃線分割
若是你肯定必定以及確定一個變量值之後不會被修改,你能夠將它的名稱使用全大寫模式改寫,暗示這是一個常量,請不要修改它的值。
遵照這條規則時須要注意的一點是,若是這個常量是一個函數,那麼應該使用駝峯式命名法。
// bad const number = 5; // good const NUMBER = 5;
每個變量聲明都應該只對應着一個變量。不該該出現像
let a = 1,b = 2;
這樣的語句。
// bad let a = 1, b = 2, c = 3; // good let a = 1; let b = 2; let c = 3;
只容許使用單引號包裹普通字符串,禁止使用雙引號。若是字符串中包含單引號字符,應該使用模板字符串。
// 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的代碼規範要出色。但無論你支持哪種,也無論你編寫的是什麼類型的代碼,最重要的是在腦海中時刻遵照着同一份代碼規範。
查看更多我翻譯的Medium文章請訪問:
項目地址: https://github.com/WhiteYin/translation
SF專欄: https://segmentfault.com/blog/yin-translation