因為項目用的vue.js框架和ES6語法,所以這套規范主要出于我們自己項目來考慮的,額,有一些太基礎的也就不寫了,大家都懂得,哈哈。
還有一點,因為我們用了 .vue
文件 ,想使用 ESlint
的話,我沒有找到很好的針對 ESlint
配置的格式化插件, 所以只能手動寫好代碼,好糾結啊。
Javascript規范
變量聲明
因為
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 使用對象字面量來創建對象
//bad
const item = new Object();
//good
const item = {};
- 2.2 當對象的屬性需要動態生成時使用計算屬性
因為這樣可以讓你將所有的屬性在一個對象的 “同一個” 地方定義
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 對象設置默認屬性時用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);
數組
- 3.1 使用字面量創建數組
//bad
const items = new Array();
//good
const items = [];
- 3.2 使用擴展符來 copy 數組
//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個字符,不應該寫為多行
// 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 如果是程序構造的字符串,用 'template strings' 替換字符串拼接
// bad
function sayHi(name) {
return 'How are you, ' + name + '?';
}
// good
function sayHi(name) {
return `How are you, ${name}?`;
}
函數
- 5.1 給函數參數一個默認值,不在函數中判斷參數
//bad
function handleThings(opts){
opts = opts || {};
}
//good
function handleThings(opts = {}){
}
- 5.2 將默認參數放在最后
// 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 函數參數(最多兩個參數)
//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作為函數參數
Flags會告訴用戶這個函數不止做一件事,但是函數應該只做一件事,所以,應該分離你的函數。
//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 當要使用函數表達式時,使用箭頭函數
使用箭頭函數更加簡明
但是當函數邏輯比較復雜時,還是需要聲明函數
-
6.2 當函數體只由單個表達式組成時,忽略掉括號。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 如果函數只由單個表達式組成時,就可以不用小括號
這樣可以減少視覺上的混淆
//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 來命名構造函數和class, 以及組件名
- 10.4 不要再變量開頭或者結尾使用下劃線
- 10.5 使用駝峰式來命名 export-default 的模塊
function makeStyleGuide() {}
export default makeStyleGuide;
-
10.6 使用PascalCase 來命名
export
的 constructor / class / singleton / function library / bare object.
使用帶類型判斷的比較判斷
使用 ===
精確的比較操作符,避免在判斷的過程中,由 JavaScript 的強制類型轉換所造成的困擾。
如果你使用 ===
操作符,那比較的雙方必須是同一類型為前提的條件下才會有效。
在只使用 ==
的情況下,JavaScript 所帶來的強制類型轉換使得判斷結果跟蹤變得復雜。
未完待續。。。。