因为项目用的vue.js框架和ES6语法,所以这套规范主要出于我们自己项目来考虑的,额,有一些太基础的也就不写了,大家都懂得,哈哈。
还有一点,因为我们用了 .vue
文件 ,想使用 ESlint
的话,我没有找到很好的针对 ESlint
配置的格式化插件, 所以只能手动写好代码,好纠结啊。
Javascript规范
变量声明
- 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 使用对象字面量来创建对象
//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
都放在的开始位置
- 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 所带来的强制类型转换使得判断结果跟踪变得复杂。
未完待续。。。。