前端項目規(guī)范

因為項目用的vue.js框架和ES6語法,所以這套規(guī)范主要出于我們自己項目來考慮的,額,有一些太基礎(chǔ)的也就不寫了,大家都懂得,哈哈。
還有一點,因為我們用了 .vue文件 ,想使用 ESlint 的話,我沒有找到很好的針對 ESlint 配置的格式化插件, 所以只能手動寫好代碼,好糾結(jié)啊。

Javascript規(guī)范


變量聲明
  • 1.1 使用 const 聲明常量。
  • 1.2 使用 let 來進行變量聲明,如不指定 let
    ,變量將被隱式地聲明為全局變量如果沒有聲明,變量處于什么定義域就變得不清。不使用 var 。

因為 let是 block scoped 不是functional scoped,懂?var則是functional scoped。另外 const 也是 block scoped。

  //bad
  let x = 10;
  let y = 100;
  //good
  let x = 10,
      y = 100;

對象

  • 2.1 使用對象字面量來創(chuàng)建對象
  //bad
  const item = new Object();
  //good
  const item = {};
  • 2.2 當對象的屬性需要動態(tài)生成時使用計算屬性

因為這樣可以讓你將所有的屬性在一個對象的 “同一個” 地方定義

function getKey(k){
  return `${k}`;
}
//bad
const person = {
  name: 'Helen',
  age: 18
};
person[getKey('beautiful')] = true;
//good
const person = {
  name: 'Helen',
  age: 18,
  [getKey('beautiful')]: true
}
  • 2.3 使用對象屬性值的shorthand
  const data = 'test';
  //bad
  const obj = {
    data: data
  };
//good
const obj = {
    data
};
  • 2.4 將使用shorthand的屬性放在對象聲明的開頭
  const anakinSkywalker = 'Anakin Skywalker';
  const lukeSkywalker = 'Luke Skywalker';
  // bad
  const obj = { 
    episodeOne: 1, 
    twoJediWalkIntoACantina: 2, 
    lukeSkywalker, 
    episodeThree: 3, 
    mayTheFourth: 4, 
    anakinSkywalker,
};
// good
   const obj = { 
    lukeSkywalker, 
    anakinSkywalker, 
    episodeOne: 1, 
    twoJediWalkIntoACantina: 2, 
    episodeThree: 3, 
    mayTheFourth: 4,
};
  • 2.5 在 invalid 的標識符上用引號
  // bad
  const bad = { 
    'foo': 3, 
    'bar': 4, 
    'data-blah': 5,
  };
// good
  const good = { 
    foo: 3, 
    bar: 4, 
    'data-blah': 5,
};
  • 2.6 不要直接用 Object.prototype上的方法,比如:hasOwnProperty, propertyIsEnumerable, isPrototypeOf。

因為這些屬性會被對象上的屬性覆蓋,比如:{ hasOwnProperty: false } 或者對象是一個null,Object.create(null)。

  //bad
  console.log(Object.hasOwnProperty(key));
  //good
  console.log(Object.prototype.hasOwnProperty.call(obj, key));
  //best
  const has = Object.prototype.hasOwnProterty;
  import has from 'has';
  console.log(has.call(obj, key));
  • 2.7 使用 'object spread operator' ,不使用 object.assign
  //very bad
  const original = {a: 1, b: 2};
  const copy = Object.assign(original, {c: 3}); //這樣會改變original ?_?

  //bad
  const original = {a: 1, b:2};
  const copy = Object.assign({}, original, {c: 3}); // copy => { a: 1, b: 2, c: 3 }

  //good
  const original = {a: 1, b: 2};
  const copy = { ...original, {c: 3}}; //copy => { a: 1, b: 2, c: 3 }

  const {a, ...test} = copy; // test => { b: 2, c: 3 }
  • 2.8 對象設(shè)置默認屬性時用Object.assign
  //bad
  const menuConfig = {
    title: null,
    body: 'Bar',
    buttonText: null,
    cancellable: true
  };
  function createMenu(config) {
  config.title = config.title || 'Foo';
  config.body = config.body || 'Bar';
  config.buttonText = config.buttonText || 'Baz';
  config.cancellable = config.cancellable === undefined ?           config.cancellable : true;
}
createMenu(menuConfig);
//good
const menuConfig = {
  title: 'Order',
  // User did not include 'body' key
  buttonText: 'Send',
  cancellable: true
};
function createMenu(config) {
    config = Object.assign({
    title: 'Foo',
    body: 'Bar',
    buttonText: 'Baz',
    cancellable: true
  }, config);

  // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
  // ...
}
createMenu(menuConfig);

數(shù)組

  • 3.1 使用字面量創(chuàng)建數(shù)組
  //bad
  const items = new Array();
  //good 
  const items = []; 
  • 3.2 使用擴展符來 copy 數(shù)組
  //bad
  const len = items.length;
  const itemsCopy = [];
  let i;
  for (i = 0; i < len; i += 1) { 
    itemsCopy[i] = items[i];
  }
//good
const itemCopy = [...items];

字符串

  • 4.1 一般字符使用單引號'',如有變量要拼的字符,使用ES6的模板字符
  let name = 'Helen';
  str = `Hello ${name}`;
  • 4.2 如果變量字符串超過100個字符,不應(yīng)該寫為多行
  // bad
  const errorMessage = 'This is a super long error that was thrown because \
                        of Batman. When you stop to think about how Batman had anything to do \
                        with this, you would get nowhere \
                        fast.';

  // bad
  const errorMessage = 'This is a super long error that was thrown because ' +
                       'of Batman. When you stop to think about how Batman had anything to do ' +
                       'with this, you would get nowhere fast.';
  
  // good
  const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
  • 4.3 如果是程序構(gòu)造的字符串,用 'template strings' 替換字符串拼接
  // bad
function sayHi(name) { 
    return 'How are you, ' + name + '?';
}
// good
function sayHi(name) { 
    return `How are you, ${name}?`;
}

函數(shù)

  • 5.1 給函數(shù)參數(shù)一個默認值,不在函數(shù)中判斷參數(shù)
  //bad
  function handleThings(opts){
    opts = opts || {};
  }
  //good
   function handleThings(opts = {}){

    }
  • 5.2 將默認參數(shù)放在最后
  // bad
  function handleThings(opts = {}, name) { 
    // ...
  }
// good
  function handleThings(name, opts = {}) { 
    // ...
  }
  • 5.3 使用‘spread operator’ ...
  // bad
  new (Function.prototype.bind.apply(Date, [null, 2016, 08, 05]));
// good
  new Date(...[2016, 08, 05]);
  • 5.4 格式上的問題
  // bad
  function foo(bar, 
               baz, 
               quux) { 
                  // body
               }
  // good
  function foo( 
              bar,
              baz, 
              quux
              ) { 
            // body
              }
// bad
console.log(foo, 
              bar, 
              baz);
// good
console.log( 
          foo, 
          bar, 
          baz,
      );
  • 5.5 函數(shù)參數(shù)(最多兩個參數(shù))
  //bad
  function createMenu(title, body, buttonText, cancellable){
    //....
  }
  //good
  function createMenu({ title, body, buttonText, cancellable}){
    //...
  }
  createMenu({
    title: 'Foo',
    body: 'Bar',
    buttonText: 'Baz',
    cancellable: true
  })
  • 5.6 不要用flags作為函數(shù)參數(shù)
    Flags會告訴用戶這個函數(shù)不止做一件事,但是函數(shù)應(yīng)該只做一件事,所以,應(yīng)該分離你的函數(shù)。
  //bad
  function createFile(name, temp) {
    if (temp) {
      fs.create(`./temp/${name}`);
    } else {
      fs.create(name);
    }
  }
//good
function createFile(name) {
    fs.create(name);
}
function createTempFile(name) {
    createFile(`./temp/${name}`);
}

Arrow Functions

  • 6.1 當要使用函數(shù)表達式時,使用箭頭函數(shù)

使用箭頭函數(shù)更加簡明
但是當函數(shù)邏輯比較復(fù)雜時,還是需要聲明函數(shù)

  • 6.2 當函數(shù)體只由單個表達式組成時,忽略掉括號。Otherwise,還是使用括號和return吧。
//bad
[1,2,3].map(number => {
  const nextNumber = number + 1;
  `A string containing the ${nextNumber}.`;
})
//good
[1,2,3].map(number => `A string containing the ${number+1}.`)
  • 6.3 如果函數(shù)只由單個表達式組成時,就可以不用小括號

這樣可以減少視覺上的混淆

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

Modules

  • 7.1 相同路徑引入的模塊放在同一個地方
  // bad 
  import foo from 'foo'; 
  // … some other imports … 
  import { named1, named2 } from 'foo';
  //good
  import foo, { named1, named2 } from 'foo';
  • 7.2 不要 export 一個變量,只有常量才能被 export
  • 7.3 當文件中只有一個export, 就是用 default export
  • 7.4 將所有的 import 都放在<script></script>的開始位置
  • 7.5
  \\ bad
  import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
  \\ good
  import {
    longNameA, 
    longNameB, 
    longNameC, 
    longNameD, 
    longNameE
  } from 'path';

注釋

  • 8.1 使用 /** ... */進行多行注釋
// good
/** 
    * make() returns a new element 
    * based on the passed-in tag name 
*/

分號

  • 9 總是使用分號

命名

  • 10.1 不要使用單個的單詞來命名,命名需要有描述性
  • 10.2 使用駝峰式命名 objects, functions, and instances
  • 10.3 使用PascalCase 來命名構(gòu)造函數(shù)和class, 以及組件名
  • 10.4 不要再變量開頭或者結(jié)尾使用下劃線
  • 10.5 使用駝峰式來命名 export-default 的模塊
 function makeStyleGuide() {}
  export default makeStyleGuide;
  • 10.6 使用PascalCase 來命名 export 的 constructor / class / singleton / function library / bare object.

使用帶類型判斷的比較判斷

使用 === 精確的比較操作符,避免在判斷的過程中,由 JavaScript 的強制類型轉(zhuǎn)換所造成的困擾。
如果你使用 === 操作符,那比較的雙方必須是同一類型為前提的條件下才會有效。
在只使用 == 的情況下,JavaScript 所帶來的強制類型轉(zhuǎn)換使得判斷結(jié)果跟蹤變得復(fù)雜。

未完待續(xù)。。。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容