本文来自 网易云社区 。
以前我们的项目编码风格一直比较混乱。前不久,我们在项目中使用了Babel,吃上了ES2015,顺便配上了ESLint。按照ESLint的rules,我们整理出一份自己的JavaScript代码规范。
配置
npm install --save-dev eslint eslint-config-rgui
然后创建.eslintrc
文件,内容如下:
{
"extends": "rgui",
"env": {
"browser": true,
"node": true
}
}
具体可以参考ESLint配置。
空白
要求使用4个空格作为缩进,禁止使用Tab。✎
indent, no-tabs, no-mixed-spaces-and-tabs
// ✗ bad
function () {
console.log('Hello');
}
// ✗ bad
function () {
——console.log('Hello');
}
// ✓ good
function () {
console.log('Hello');
}
强制使用Unix换行符\n
,禁止使用Windows换行符\r\n
✎
禁止使用Unicode字节顺序标记(BOM)。✎
要求文件末尾有且只有一个空行。✎
// ✗ bad
(function (global) {
// ...stuff...
})(this);
// ✗ bad
(function (global) {
// ...stuff...
})(this);↵
↵
// ✓ good
(function (global) {
// ...stuff...
})(this);↵
禁止连续出现多个空行。✎
// ✗ bad
const value = 'Hello';
console.log(value);
// ✓ good
const value = 'Hello';
console.log(value);
禁止块的内边缘出现空行。✎
// ✗ bad
function bar() {
console.log(foo);
}
// ✓ good
function bar() {
console.log(foo);
}
要求运行指令之后必须有一个空行。✎
// ✗ bad
'use strict';
let foo;
// ✓ good
'use strict';
let foo;
禁止行尾出现空格。✎
禁止连续出现多个空格。✎
// ✗ bad
let a = 1;
if(foo === 'bar') {}
a << b
let arr = [1, 2];
a ? b: c;
// ✓ good
let a = 1;
if(foo === 'bar') {}
a << b
let arr = [1, 2];
a ? b: c;
要求分号、逗号、冒号之后必须有一个空格。✎
semi-spacing, comma-spacing, key-spacing
// ✗ bad
const arr = [1,2,3,4];
const obj = { id:1,name:'Alice' };
foo(a,b,c);
for (let i = 0;i < 10;i++)
// ✓ good
const arr = [1, 2];
const obj = { id: 1, name: 'Alice' };
foo(a, b, c);
for (let i = 0; i < 10; i++)
禁止点号(属性、rest参数、扩展运算符)和单词之间有空格。✎
no-whitespace-before-property, rest-spread-spacing
// ✗ bad
foo. bar. baz();
fn(... args);
[... arr, 4, 5, 6];
// ✓ good
foo.bar.baz();
fn(...args);
[...arr, 4, 5, 6];
要求一元运算符周围没有空格,等号、二元运算符、箭头符号周围有一个空格。✎
space-unary-ops, space-infix-ops, arrow-spacing
// ✗ bad
i ++;
let x=-y*5;
let message='Hello, '+name+'!';
const func=(x)=>{};
// ✓ good
i++;
let x = -y * 5;
let message = 'Hello, ' + name + '!';
const func = (x) => {};
禁止在小括号(表达式、函数)和中括号(数组、属性)内边缘加空格,要求在大括号(对象、单行代码块)内边缘加一个空格。✎
space-in-parens, array-bracket-spacing, computed-property-spacing, object-curly-spacing, block-spacing
// ✗ bad
const num = 3 * ( 2 + 5 );
function hello( name ) {
console.log( 'Hi,', name );
}
if ( test ) {
thing();
}
// ✓ good
const num = 3 * (2 + 5);
function hello(name) {
console.log('Hi,', name);
}
if (test) {
thing();
}
// ✗ bad
const arr = [ 1, 2, 3 ];
const [ x, y ] = z;
obj[ key ] = 'test';
user[ 'name' ] = 'John';
// ✓ good
const arr = [1, 2, 3];
const [x, y] = z;
obj[key] = 'test';
user['name'] = 'John';
// ✗ bad
const obj = {id: 1, name: 'Alice'};
const {x, y} = z;
function foo() {return true;}
if (foo) { bar = 0;}
// ✓ good
const obj = { id: 1, name: 'Alice' };
const { x, y } = z;
function foo() { return true; }
if (foo) { bar = 0; }
// ✗ bad
product.attr({price: 10.6, tags: ['food', 'sweet']});
product.attr( { price: 10.6, tags: [ 'food', 'sweet' ] } );
// ✓ good
product.attr({ price: 10.6, tags: ['food', 'sweet'] });
要求在大括号前放一个空格。✎
// ✗ bad
function test(){
console.log('test');
}
// ✓ good
function test() {
console.log('test');
}
// ✗ bad
dog.set('attr',{
age: '1 year',
breed: 'Bernese Mountain Dog',
});
// ✓ good
dog.set('attr', {
age: '1 year',
breed: 'Bernese Mountain Dog',
});
要求在关键字和小括号之间加一个空格,禁止在函数名和参数列表之间加空格。✎
keyword-spacing, func-call-spacing, space-before-function-paren
保持一致是最好的,你不需要在添加/删除函数名时,考虑要不要添加/删除空格。
// ✗ bad
if(isJedi) {
fight ();
} else {
chat ();
}
// ✓ good
if (isJedi) {
fight();
} else {
chat();
}
// ✗ bad
function fight () {
console.log ('Swooosh!');
}
run(function() {
console.log ('Swooosh!');
});
// ✓ good
function fight() {
console.log('Swooosh!');
}
run(function () {
console.log('Swooosh!');
});
禁止出现空块语句或空函数,除非添加一个注释。
// ✗ bad
if (cond) {
}
while (cond) { }
// ✓ good
if (cond) {
// TODO
}
while (cond) { /* TODO */ }
// ✗ bad
function foo() {}
const foo = function () {};
const foo = () => {};
// ✓ good
function foo() { /* noop */ }
const foo = function () { /* noop */ };
const foo = () => { /* noop */ };
要求大括号风格使用:1tbs
(one true brace style)格式,允许单行模式。✎
// ✗ bad
function foo()
{
return true;
}
if (foo) {
bar();
}
else {
baz();
}
try
{
somethingRisky();
} catch(e)
{
handleError();
}
// ✓ good
function foo() {
return true;
}
if (foo) {
bar();
} else {
baz();
}
try {
somethingRisky();
} catch(e) {
handleError();
}
function func() { return true; }
if (foo) { bar(); }
要求遵循大括号约定:multi-or-nest
方式,多行时使用大括号,单行时省略大括号。✎
// ✗ bad
if (!obj)
obj = {
id: 1,
name: 'alice',
};
while (cond)
if (cond2)
doSomething();
else
doSomethingElse();
if (foo) {
foo++;
}
while (cond) {
doSomething();
}
for (let i = 0; i < count; i++) {
doSomething();
}
// ✓ good
if (!obj) {
obj = {
id: 1,
name: 'alice',
};
}
while (cond) {
if (cond2)
doSomething();
else
doSomethingElse();
}
if (foo)
foo++;
while (cond)
doSomething();
for (let i = 0; i < count; i++)
doSomething();
要求单行语句必须换行。✎
nonblock-statement-body-position
// ✗ bad
if (foo) return;
while (cond) doSomething();
for (let i = 0; i < count; i++) doSomething();
// ✓ good
if (foo)
return;
while (cond)
doSomething();
for (let i = 0; i < count; i++)
doSomething();
分号和逗号
强制使用分号,禁止多余的分号。✎
semi, no-extra-semi, no-unexpected-multiline
// ✗ bad
(function () {
const name = 'Skywalker'
return name;;
})()
// ✓ good
(function () {
const name = 'Skywalker';
return name;
})();
禁止使用行首逗号。✎
// ✗ bad
const story = [
once
, upon
, aTime
];
// ✓ good
const story = [
once,
upon,
aTime,
];
禁止使用逗号操作符。
// ✗ bad
foo = doSomething(), val;
if (doSomething(), !!test);
while (val = foo(), val < 42);
// ✓ good
doSomething();
foo = val;
if (!!test);
while ((val = foo()) < 42);
要求多行使用拖尾逗号,禁止单行使用拖尾逗号。✎
这会使git diffs更简洁,使编辑器的上下移动快捷键更方便。不用担心IE8会报错,Babel等编译器会自动去除拖尾逗号。
// ✗ bad - git diff without trailing comma const hero = { firstName: 'Florence', - lastName: 'Nightingale' + lastName: 'Nightingale', + inventorOf: ['coxcomb chart', 'modern nursing'] }; // ✓ good - git diff with trailing comma const hero = { firstName: 'Florence', lastName: 'Nightingale', + inventorOf: ['coxcomb chart', 'modern nursing'], };
// ✗ bad
const hero = {
firstName: 'Dana',
lastName: 'Scully'
};
const heroes = [
'Batman',
'Superman'
];
// ✓ good
const hero = {
firstName: 'Dana',
lastName: 'Scully',
};
const heroes = [
'Batman',
'Superman',
];
// ✗ bad
const hero = { firstName, lastName, };
const arr = [1, 2, 3, ];
// ✓ good
const hero = { firstName, lastName };
const arr = [1, 2, 3];
字符串
要求使用单引号包裹字符串,在需要插值或换行时才使用反引号,在内部单引号需要转义时才使用双引号。✎
// ✗ bad
const hello = "Hello, Bob!";
const element = `<div class="box"></div>`;
const message = 'I don\'t like quotes.';
// ✓ good
const hello = 'Hello, Bob!';
const element = `<div class="${className}"></div>`;
const message = "I don't like quotes.";
禁止不必要的字符拼接。
// ✗ bad
const a = 'some' + 'string';
const a = '1' + '0';
// ✓ good
const c = 'somestring';
const a = '10';
禁止使用不必要的转义符。
// ✗ bad
const foo = '\"This\" \i\s \'quoted\'';
// ✓ good
const foo = '"This" is \'quoted\'';
const foo = `"This" is 'quoted'`;
禁止使用多行字符串。
// ✗ bad
const message = 'Hello \
world';
// ✓ good
const message = `Hello
world`;
尽量使用模板字符串,禁止在模板字符串的大括号周围加空格。✎
prefer-template, template-curly-spacing
// ✗ bad
return 'How are you, ' + name + '?';
return ['How are you, ', name, '?'].join();
return `How are you, ${ name }?`;
// ✓ good
return `How are you, ${name}?`;
对象和属性
要求点操作符和属性放在同一行。✎
// ✗ bad
$('#items').
find('.selected').
highlight().
end().
find('.open').
updateCount();
// ✓ good
$('#items')
.find('.selected')
.highlight()
.end()
.find('.open')
.updateCount();
$('#items').find('.selected').highlight().end().find('.open').updateCount();
// ✗ bad
const p = promise.
then(function() {
// code
}).
catch(function() {
// code
});
// ✓ good
const p = promise.then(function() {
// code
}).catch(function() {
// code
});
要求尽可能使用点号,且不回避关键字。✎
// ✗ bad
const result = luke['jedi'];
// ✓ good
const result = luke.jedi;
const result = luke.class;
const result = luke[key];
禁止使用不必要的计算属性。✎
// ✗ bad
const user = { ['name']: 'John Doe' };
// ✓ good
const user = { name: 'John Doe' };
要求使用对象属性的简写语法。✎
// ✗ bad
const atom = {
value: value,
add: function (value) {
return atom.value + value;
},
};
// ✓ good
const atom = {
value,
add(value) {
return atom.value + value;
},
};
要求只给对象中需要的属性名加引号。✎
// ✗ bad
const bad = {
'foo': 3,
'bar': 4,
'>5,
};
// ✓ good
const good = {
foo: 3,
bar: 4,
'>5,
};
运算符
强制使用===
和==
,禁止使用==
和!=
。
该规则旨在消除非类型安全的相等操作符。例如以下语句均被认为是
true
:
[] == false
[] == ![]
3 == "03"
// ✗ bad
if (a == b)
if (foo == true)
if (bananas != 1)
if (value == undefined)
if (typeof foo == 'undefined')
if ('hello' != 'world')
if (0 == 0)
if (true == true)
if (foo == null)
// ✓ good
if (a === b)
if (foo === true)
if (bananas !== 1)
if (value === undefined)
if (typeof foo === 'undefined')
if ('hello' !== 'world')
if (0 === 0)
if (true === true)
if (foo === null)
禁止出现Yoda条件,除非是在范围中使用。✎
// ✗ bad
if ('red' === color)
if (true == flag)
if (-1 < str.indexOf(substr))
// ✓ good
if (color === 'red')
if (flag)
if (0 <= x && x < 1)
要求把换行符放在运算符的前面。
// ✗ bad
let fullHeight = borderTop +
innerHeight +
borderBottom;
if (someCodition ||
otherCondition) {
// ...
}
// ✓ good
let fullHeight = borderTop
+ innerHeight
+ borderBottom;
if (someCodition
|| otherCondition) {
// ...
}
相关阅读:
本文来自网易云社区,经作者赵雨森授权发布。