Airbnb前端規範之javascript編碼規範

來源:互聯網
上載者:User

標籤:strong   asc   函數運算式   irb   exp   array   col   3.1   提升   

1 引用

1.1 對所有的引用使用 const ,不要使用 var。

(這能確保你無法對引用重新賦值,也不會導致出現 bug 或難以理解)

// bad  var a = 1;  var b = 2;// good  const a = 1;  const b = 2;
1.2 如果一定需要可變動的引用,使用 let 代替 var。

(因為 let 是塊級範圍,而 var 是函數範圍。)

// bad  var count = 1;  if (true) {    count += 1;  }// good, use the let.  let count = 1;  if (true) {    count += 1;  }
2  對象2.1 使用字面值建立對象。
// badconst item = new Object();// goodconst item = {};
2.2 使用對象方法的簡寫。
// badconst atom = {  value: 1,  addValue: function (value) {    return atom.value + value;  },};// goodconst atom = {  value: 1,  addValue(value) {    return atom.value + value;  },};
2.3 使用對象屬性值的簡寫。
const lukeSkywalker = ‘Luke Skywalker‘;// bad  const obj = {    lukeSkywalker: lukeSkywalker,  };// good  const obj = {    lukeSkywalker,  };
2.4 不要直接調用 Object.prototype 的方法,如:hasOwnProperty, propertyIsEnumerable, 和 isPrototypeOf
// badconsole.log(object.hasOwnProperty(key));// goodconsole.log(Object.prototype.hasOwnProperty.call(object, key));// bestconst has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope./* or */const has = require(‘has‘);…console.log(has.call(object, key));

 

2.5 淺拷貝對象的時候最好是使用 … 操作符而不是 Object.assign
// very badconst original = { a: 1, b: 2 };const copy = Object.assign(original, { c: 3 }); // this mutates `original`delete copy.a; // so does this
// badconst original = { a: 1, b: 2 };const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }// goodconst original = { a: 1, b: 2 };const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }const { a, ...noA } = copy; // noA => { b: 2, c: 3 }

 

3 數組3.1 使用字面值建立數組。eslint: no-array-constructor
// badconst items = new Array();// goodconst items = [];
3.2 使用拓展運算子 … 複製數組。
// badconst items = new Array();// goodconst items = [];// badconst len = items.length;const itemsCopy = [];let i;for(i = 0;i <len;i++){  itemsCopy[i] = items[i];}// goodconst itemsCopy = [...items];
3.3 使用 Array#from 把一個類數組對象轉換成數組
const foo = document.querySelectorAll(‘.foo‘);const nodes = Array.from(foo);
4 函數4.1 使用函式宣告代替函數運算式

為什嗎?因為函式宣告是可命名的,所以他們在調用棧中更容易被識別。此外,函式宣告會把整個函數提升(hoisted),而函數運算式只會把函數的引用變數名提升。這條規則使得箭頭函數可以取代函數運算式。

// bad  const foo = function () {  };  // good  function foo() {  }
4.2 函數運算式:
// 立即調用的函數運算式 (IIFE)(() => {   console.log(‘Welcome to the Internet. Please follow me.‘);})();
4.3 永遠不要在一個非函數代碼塊(if、while 等)中聲明一個函數,把那個函數賦給一個變數。瀏覽器允許你這麼做,但它們的解析表現不一致
// badif (currentUser) {  function test() {    console.log(‘Nope.‘);  }}// goodlet test;if (currentUser) {  test = () => {    console.log(‘Yup.‘);  };}
4.4 不要使用 arguments。可以選擇 rest 文法 … 替代

為什嗎?使用 … 能明確你要傳入的參數。另外 rest 參數是一個真正的數組,而 arguments 是一個類數組。

// bad  function concatenateAll() {    const args = Array.prototype.slice.call(arguments);    return args.join(‘‘);  }  // good  function concatenateAll(...args) {    return args.join(‘‘);  }

 

5 箭頭函數5.1 當你必須使用函數運算式(或傳遞一個匿名函數)時,使用箭頭函數符號。

為什麼?因為箭頭函數創造了新的一個 this 執行環境(譯註:參考 Arrow functions - JavaScript | MDN 和 ES6 arrow functions, syntax and lexical scoping),通常情況下都能滿足你的需求,而且這樣的寫法更為簡潔。

為什麼不?如果你有一個相當複雜的函數,你或許可以把邏輯部分轉移到一個函式宣告上。

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

 

5.2 如果一個函數適合用一行寫出並且只有一個參數,那就把花括弧、圓括弧和 return 都省略掉。如果不是,那就不要省略

為什嗎?文法糖。在鏈式調用中可讀性很高。 
為什麼不?當你打算回傳一個對象的時候。

  // good  [1, 2, 3].map(x => x * x);  // good  [1, 2, 3].reduce((total, n) => {    return total + n;  }, 0);
6 構造器6.1 總是使用 class。避免直接操作 prototype

為什麼? 因為 class 文法更為簡潔更易讀。

// bad  function Queue(contents = []) {    this._queue = [...contents];  }  Queue.prototype.pop = function() {    const value = this._queue[0];    this._queue.splice(0, 1);    return value;  }  // good  class Queue {    constructor(contents = []) {      this._queue = [...contents];    }    pop() {      const value = this._queue[0];      this._queue.splice(0, 1);      return value;    }  }

  

6.2 使用 extends 繼承。

為什嗎?因為 extends 是一個內建的原型繼承方法並且不會破壞 instanceof。

6.3 方法可以返回 this 來協助鏈式調用。7 模組7.1 總是使用模組 (import/export)7.2 不要使用萬用字元 import
// bad  import * as AirbnbStyleGuide from ‘./AirbnbStyleGuide‘;// good  import AirbnbStyleGuide from ‘./AirbnbStyleGuide‘;

  

7.3 不要從 import 中直接 export
// bad  // filename es6.js  export { es6 as default } from ‘./airbnbStyleGuide‘;// good  // filename es6.js  import { es6 } from ‘./AirbnbStyleGuide‘;  export default es6;

  

8 Iterators and Generators8.1 不要使用 iterators,使用高階函數例如 map() 和 reduce() 替代 for-of

為什嗎?這加強了我們不變的規則。處理純函數的回調值更易讀,這比它帶來的副作用更重要。

 const numbers = [1, 2, 3, 4, 5];  // bad  let sum = 0;  for (let num of numbers) {    sum += num;  }  sum === 15;  // good  let sum = 0;  numbers.forEach((num) => sum += num);  sum === 15;  // best (use the functional force)  const sum = numbers.reduce((total, num) => total + num, 0);  sum === 15;

 

8.2 現在還不要使用 generators?

為什嗎?因為它們現在還沒法很好地編譯到 ES5。 (目前Chrome 和 Node.js 的穩定版本都已支援 generators)

9 變數9.1 一直使用 const 來聲明變數

如果不這樣做就會產生全域變數。我們需要避免全域命名空間的汙染。

// badsuperPower = new SuperPower();// goodconst superPower = new SuperPower();

  

9.2 使用 const 聲明每一個變數

為什嗎?增加新變數將變的更加容易,而且你永遠不用再擔心調換錯 ; 跟 ,。

9.3 將所有的 const 和 let 分組

為什嗎?當你需要把已賦值變數賦值給未賦值變數時非常有用。

  // bad  let i, len, dragonball,      items = getItems(),      goSportsTeam = true;  // bad  let i;  const items = getItems();  let dragonball;  const goSportsTeam = true;  let len;  // good  const goSportsTeam = true;  const items = getItems();  let dragonball;  let i;  let length;
9.4 在你需要的地方給變數賦值,但請把它們放在一個合理的位置

let 和 const 是塊級範圍而不是函數範圍。

10 提升10.1 var 聲明會被提升至該範圍的頂部,但它們賦值不會提升。

let 和 const 被賦予了一種稱為「暫時性死區(Temporal Dead Zones, TDZ)」的概念。這對於瞭解為什麼 type of 不再安全相當重要。

10.2 匿名函數運算式的變數名會被提升,但函數內容並不會。10.3 命名的函數運算式的變數名會被提升,但函數名和函數函數內容並不會。10.4 函式宣告的名稱和函數體都會被提升。11 比較子 & 等號11.1 優先使用 === 和 !== 而不是 == 和 !=.11.2 條件運算式例如 if 語句通過抽象方法 ToBoolean 強制計算它們的運算式並且總是遵守下面的規則:

o 對象 被計算為 true 
o Undefined 被計算為 false 
o Null 被計算為 false 
o 布爾值 被計算為 布爾的值 
o 數字 如果是 +0、-0、或 NaN 被計算為 false, 否則為 true 
o 字串 如果是Null 字元串 ” 被計算為 false,否則為 true

12 注釋12.1 使用 / * … / 作為多行注釋。包含描述、指定所有參數和傳回值的類型和值。
// bad// make() returns a new element// based on the passed in tag name//// @param {String} tag// @return {Element} elementfunction make(tag) {  // ...stuff...  return element;}// good/** * make() returns a new element * based on the passed in tag name * * @param {String} tag * @return {Element} element */function make(tag) {  // ...stuff...  return element;}

  

12.2 使用 // 作為單行注釋。在注釋對象上面另起一行使用單行注釋。在注釋前插入空行。12.3 給注釋增加 FIXME 或 TODO 的首碼

協助其他開發人員快速瞭解這是一個需要複查的問題,或是給需要實現的功能提供一個解決方式。這將有別於常見的注釋,因為它們是可操作的。使用 FIXME – need to figure this out 或者 TODO – need to implement。

12.4 使用 // FIXME: 標註問題。
class Calculator {  constructor() {    // FIXME: shouldn‘t use a global here    total = 0;  }}

  

12.5 使用 // TODO: 標註問題的解決方式。
class Calculator {  constructor() {    // TODO: total should be configurable by an options param    this.total = 0;  }}
13 空白13.1 使用 2 個空格作為縮排。13.2 在花括弧前要放一個空格。13.3 在控制語句(if、while 等)的小括弧前放一個空格。

在函數調用及聲明中,不在函數的參數列表前加空格。

13.4 在檔案末尾插入一個空行。13.5 在使用長方法鏈時進行縮排。使用放置在前面的點 . 強調這是方法調用而不是新語句。

Airbnb前端規範之javascript編碼規範

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.