eslint推荐编码规范和airbnb推荐编码规范
Posted sophiehui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了eslint推荐编码规范和airbnb推荐编码规范相关的知识,希望对你有一定的参考价值。
Eslint规范
-
for 循环禁止使用无限循环(这个非默认推荐)
// bad for (var i = 0; i < 10; i--) { } for (var i = 10; i >= 0; i++) { } // good for (var i = 0; i < 10; i++) { }
-
不允许和负0比较
// bad if (x === -0) { // doSomething()... } // good if (x === 0) { // doSomething()... } if (Object.is(x, -0)) { // doSomething()... }
-
禁止在条件语句(if,while,do...while )中出现赋值操作
// bad if (user.jobTitle = "manager") { // user.jobTitle is now incorrect } // good if (user.jobTitle == "manager") { // doSomething()... }
注意:该规则有个字符串选项,默认是“except-parens”,允许出现赋值操作,但必须是被圆括号括起来的;设置为“always”表示禁止在条件语句中出现赋值语句
// bad 设置为except-parens var x; if (x = 0) { var b = 1; } function setHeight(someNode) { "use strict"; do { someNode.height = "100px"; } while (someNode = someNode.parentNode); } // good 设置为except-parens var x; if (x === 0) { var b = 1; } function setHeight(someNode) { "use strict"; do { someNode.height = "100px"; } while ((someNode = someNode.parentNode)); }
-
禁止在代码中使用console(在产品发布之前,剔除console的调用)
// bad console.log("Log a debug level message."); console.warn("Log a warn level message."); console.error("Log an error level message.") // good //自定义的Console Console.log("Log a debug level message.");
注意:可以设置allow参数允许console 对象方法
-
禁止在条件语句(for,if,while,do...while)和三元表达式(?:)中使用常量表达式
// bad if (false) { doSomething(); } if (2) { doSomething(); } for (;-2;) { doSomething(); } while (typeof x) { doSomething(); } do{ doSomething(); } while (x = -1); var result = 0 ? a : b; // good if (x === 0) { doSomething(); } for (;;) { doSomething(); } while (typeof x === "undefined") { doSomething(); } do{ doSomething(); } while (x); var result = x !== 0 ? a : b;
注意:可以通过设置checkLoops参数来表示是否允许使用常量表达式
-
禁用debugger,采用断点的方式进行调试
// bad function isTruthy(x) { debugger; return Boolean(x); } // good function isTruthy(x) { return Boolean(x); // set a breakpoint at this line }
-
不允许在函数(function)定义里面出现重复的参数(箭头函数和类方法设置重复参数会报错,但跟该规则无关)
// bad function foo(a, b, a) { console.log("value of the second a:", a); } var bar = function (a, b, a) { console.log("value of the second a:", a); }; // good function foo(a, b, c) { console.log(a, b, c); } var bar = function (a, b, c) { console.log(a, b, c); }; // 箭头函数报错 function foo(x, x, y = 1) { //doSomething(); } // SyntaxError: Duplicate parameter name not allowed in this context
-
不允许对象字面量出现重复的key
// bad var foo = { bar: "baz", bar: "qux" }; var foo = { "bar": "baz", bar: "qux" }; var foo = { 0x1: "baz", 1: "qux" }; // good var foo = { bar: "baz", foo: "foo" };
-
不允许使用重复的case值
// bad var a = 1; var b = 1; switch (a) { case 1: break; case 2: break; case 1: // duplicate test expression break; default: break; } switch (a) { case b: break; case 2: break; case b: // duplicate test expression break; default: break; } switch (a) { case \'1\': break; case 2: break; case \'1\': // duplicate test expression break; default: break; } //good var a = 1; switch (a) { case 1: break; case 2: break; case 3: // duplicate test expression break; default: break; }
-
不允许出现空块语句
// bad if (foo) { } try { doSomething(); } catch(ex) { } finally { } //good if (foo) { // empty } try { doSomething(); } catch (ex) { // continue regardless of error }
注意:可以通过allowEmptyCatch为true允许出现空的catch子句
-
不允许在正则表达式中出现空字符集
// bad /^abc[]/.test("abcdefg"); // false "abcdefg".match(/^abc[]/); // null // good /^abc/.test("abcdefg"); // true "abcdefg".match(/^abc/); // ["abc"] /^abc[a-z]/.test("abcdefg"); // true "abcdefg".match(/^abc[a-z]/); // ["abcd"]
-
不允许对catch子句的参数进行重新赋值
// bad try { // code } catch (e) { e = 10; } // good try { // code } catch (e) { var foo = 10; }
-
禁止不必要的布尔类型转换
// bad var bar = \'zhinanzhen\'; var foo = !!!bar;//与!bar值相同,都为false var foo = !!bar ? baz : bat; var foo = Boolean(!!bar); if (Boolean(foo)) { // ... } // good var foo = !!bar;//转布尔值 var foo = Boolean(bar); function foo() { return !!bar; } var foo = bar ? !!baz : !!bat;
-
禁止不必要的分号和括号
// bad var x = 5;; function foo() { // code }; a = (b * c); // good var x = 5; var foo = function() { // code } a = b * c;
-
不允许对function重新赋值
// bad var bar = 5;; function foo() {} foo = bar; function foo() { foo = bar; } // good var foo = function () {} foo = bar; function foo(foo) { // `foo` is shadowed. foo = bar; } function foo() { var foo = bar; // `foo` is shadowed. }
-
不允许在嵌套的语句块中用var声明变量和function
// bad if (test) { function doSomethingElse () { //code } } // good function doSomething() { const a = 1; }
注意:
- "functions" (默认) 禁止 function 声明出现在嵌套的语句块中
- "both" 禁止 function 和 var 声明出现在嵌套的语句块中
-
不允许在正则表达式中使用控制字符,即不可显示的字符(在ASCII码中,第0~31号及第127号是控制字符或通讯专用字符)
// bad var pattern1 = /\\x1f/; var pattern2 = new RegExp("\\x1f");
// good var pattern1 = /\\x20/; var pattern2 = new RegExp("\\x20");
```
-
不允许RegExp构造函数中出现无效的正则表达式
// bad RegExp(\'[\');//无效,报错,RegExp(\'[]\')有效 // good RegExp(\'.\');//\'.\'元字符查找单个字符
-
不允许正则表达式字面量中出现多个空格
// bad var re = /foo bar/; // good var re = /foo {3}bar/;
-
定义函数时,空格的使用(参考airbnb规范的30-34条)
// bad function thing() /*<NBSP>*/{//使用了多个空格 return \'test\'; } function thing( /*<NBSP>*/){ return \'test\'; } // good function thing() { return \'test\'; } function thing(/*<NBSP>*/) { return \'test\'; }
注意:
- "skipStrings": true (默认) 允许在字符串字面量中出现任何空白字符
- "skipComments": true 允许在注释中出现任何空白字符
- "skipRegExps": true 允许在正则表达式中出现任何空白字符
- "skipTemplates": true 允许在模板字面量中出现任何空白字符
-
不允许将全局对象(这里主要指非函数型和非构造器对象的全局对象,例如:NaN,Infinity,undefined,Math,JSON,Reflect)作为函数进行调用
// bad var math = Math(); var json = JSON(); var reflect = Reflect(); // good function area(r) { return Math.PI * r * r; } var object = JSON.parse("{}"); var value = Reflect.get({ x: 1, y: 2 }, "x");
-
不允许使用稀疏数组
// bad var items = [,]; var colors = [ "red",, "blue" ]; // good var items = []; var items = new Array(23); var colors = [ "red", "blue", ];
-
不允许使用多行表达式(使用分号结尾,避免无关的两条语句被解析成一条语句)
// bad var hello = \'world\' [1, 2, 3].forEach(addNumber); // good ar hello = \'world\'; [1, 2, 3].forEach(addNumber);
-
不允许在return,throw,continue,break后出现执行不到的代码
// bad function foo() { return true; console.log("done"); } // good function bar() { let x = 1; return x; }
-
不允许直接在finally语句中出现控制流语句(return,throw,break,continue)
// bad let foo = function() { try { return 1; } catch(err) { return 2; } finally { return 3; } }; // good let foo = function() { try { return 1; } catch(err) { return 2; } finally { console.log("hola!"); } }; //间接使用 let foo = function() { try { return 1; } catch(err) { return 2; } finally { let a = function() { return "hola!"; } } };
-
否定操作的使用
// bad if (!key in object) { // doSomthing() } // good if (!(key in object)) { // doSomthing() }
-
检查非数值(NaN)必须使用isNaN()
// bad if (foo == NaN) { // doSomthing() } // good if (isNaN(foo)) { // doSomthing() }
-
typeof 表达式必须与有效的字符串进行比较
// bad typeof foo === "strnig" typeof foo == "undefimed" // good typeof foo === "string" typeof bar == "undefined"
-
不允许在case和default语句中出现词法声明(let,const,function,class),如果需要使用,必须使用花括号
// bad switch (foo) { case 1: let x = 1; break; case 2: const y = 2; break; case 3: function f() {} break; default: class C {} } // good switch (foo) { // The following case clauses are wrapped into blocks using brackets case 1: { let x = 1; break; } case 2: { const y = 2; break; } case 3: { function f() {} break; } case 4: // Declarations using var without brackets are valid due to function-scope hoisting var z = 4; break; default: { class C {} } }
-
不允许case语句落空,可以用throw、return、break或者注释作为结束
// bad switch(foo) { case 1: doSomething(); case 2: doSomethingElse(); } // good switch(foo) { case 1: doSomething(); break; case 2: doSomething(); } switch(foo) { //如果有意落空case语句,需设置commentPattern参数,并且加上注释 case 1: doSomething(); // break omitted case 2: doSomethingElse(); }
-
不允许使用空的解构模式
// bad var {} = foo; var [] = foo; var {a: {}} = foo; var {a: []} = foo; function foo({}) {} function foo([]) {} function foo({a: {}}) {} function foo({a: []}) {} // good var {a = {}} = foo; var {a = []} = foo; function foo({a = {}}) {} function foo({a = []}) {}
-
不允许修改只读的全局变量
// bad Object = null; undefined = 1; window = {};
-
不允许使用8进制字面量(即用0开头的数字)
// bad var num = 071; var result = 5 + 07; // good var num = "071";
-
不允许多次声明同一个变量
// bad var a = 3; var a = 10; // good var a = 3; a = 10;
注意: “builtinGlobals”如果设置为 true,该规则也会检查全局内置对象,比如Object、Array、Number…
-
不允许自己给自己赋值
// bad foo = foo; [a, b] = [a, b]; [a, ...b] = [x, ...b]; ({a, b} = {a, x}); // good foo = bar; [a, b] = [b, a]; let foo = foo;
-
不允许使用没有使用过的标签
// bad A: for (let i = 0; i < 10; ++i) { foo(); } // good B: for (let i = 0; i < 10; ++i) { if (foo()) { break B; } bar(); }
-
不允许使用没有必要的转义
// bad "\\\'"; \'\\"\'; "\\#"; "\\e"; `\\"`; `\\"${foo}\\"`; `\\#{foo}`; /\\!/; /\\@/; // good "\\""; \'\\\'\'; "\\x12"; "\\u00a9"; "\\371"; "xs\\u2111"; `\\``; `\\${${foo}\\}`; `$\\{${foo}\\}`; /\\\\/g; /\\t/g; /\\w\\$\\*\\^\\./;
-
不允许删除变量(严格模式下会报错)
// bad var x; delete x;
-
不允许使用未声明的变量
// bad b = 10; //good let b = 10;
-
定义过的变量都必须被使用
//good let b = 10; alert(b);
-
不允许使用空格和tab混合缩进(airbnb推荐使用两个空格作为缩进)
-
派生类中的构造函数必须调用 super()。非派生类的构造函数不能调用 super()
//bad class A { constructor() { super(); // This is a SyntaxError. } } class A extends B { constructor() { } // Would throw a ReferenceError. } //good class A { constructor() { } } class A extends B { constructor() { super(); } }
-
在派生类构造函数中,不允许在调用super()之前使用this和super
// bad class A extends B { constructor() { this.a = 0; super(); } } class A extends B { constructor() { super.foo(); super(); } } //good class A { constructor() { this.a = 0; // OK, this class doesn\'t have an `extends` clause. } } class A extends B { constructor() { super(); this.a = 0; // OK, this is after `super()`. } }
-
不允许修改类声明的变量
// bad class A { } A = 0; class A { b() { A = 0; } } //good let A = class A { } A = 0; // A is a variable. let A = class { b() { A = 0; // A is a variable. } }
-
禁止修改const声明的变量
// bad const a = 0; a = 1; //good const a = 0; alert(a);
-
Symbol函数前不能使用new命令
// bad var foo = new Symbol("foo"); //good var foo = Symbol("foo"); function bar(Symbol) { const baz = new Symbol("baz"); }
-
不允许使用没有yield的generator 函数
// bad function* foo() { return 10; } //good function* foo() { yield 5; return 10; }
Airbnb规范
-
使用const声明只读的常量,使用let声明可变的变量
// bad var a = 1; var b = 4; if(b > a){ a += 1; } //good let a = 1; const b = 2; if(b > a){ a += 1; }
-
使用字面量创建对象和数组
// bad const item = new Object(); const items = new Array(); //good const item = {}; const items = [];
-
不允许使用关键字作为变量和键值
// bad const default = 0; const superman = { default: { clark: \'kent\' }, private: true }; //good const defaults = 0; const superman = { defaults: { clark: \'kent\' }, hidden: true, };
-
向数组添加元素时,使用push函数,不允许使用直接赋值的方式
// bad let items = []; items[items.length] = \'zhinanzhen\'; //good let items = []; items.push(\'zhinanzhen\');
-
使用解构赋值的方式复制数组
// bad const len = items.length; const itemsCopy = []; let i; for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; } //good const itemsCopy = [...items];
-
对象转数组使用数组的from方法
const foo = document.querySelectorAll(\'.foo\'); const nodes = Array.from(foo);
-
推荐使用解构存取和多属性对象
// bad function getFullName(user) { const firstName = user.firstName; const lastName = user.lastName; return `${firstName} ${lastName}`; } //good function getFullName(obj) { const { firstName, lastName } = obj; return `${firstName} ${lastName}`; } //best function getFullName({ firstName, lastName }) { return `${firstName} ${lastName}`; }
-
数组推荐使用解构赋值
const arr = [1, 2, 3, 4]; const [first, second] = arr;
-
字符串使用单引号(eslint推荐使用一致的单引号或者双引号)
// bad const name = "zhinanzhen"; // good const name = \'zhinanzhen\';
-
***推荐使用模版字符串
function sayHi(name) { return `How are you, ${name}?`; }
-
推荐使用函数声明代替函数表达式(var声明的函数表达式,函数的声明会被提升,但是函数体不会;函数声明的名称和函数体都会被提升)
// bad const foo = function () { //doSomething(); }; // good function foo() { const foo = function () { //doSomething(); }; }
-
不允许在if,while中声明一个函数
// bad let a = 2; if (a > 0){ function foo(){ //doSomething() } }
-
不允许把参数声明为arguments(eslint: 不允许函数的参数重名),且使用rest语法代替arguments
// bad function nope(name, options, arguments) { // ...stuff... } // bad function concatenateAll() { const args = Array.prototype.slice.call(arguments); return args.join(\'\'); } // good function concatenateAll(...args) { return args.join(\'\'); }
-
不允许直接给函数的参数赋值
// bad var b = 1; function count(a = b++) { console.log(a); } count(); // 1 count(); // 2 count(3); // 3 count(); // 3
-
在必须使用函数表达式或者传递一个匿名函数时,使用箭头函数
// bad [1, 2, 3].map(function (x) { return x * x; }); // good [1, 2, 3].map((x) => { return x * x; });
-
推荐使用class,避免直接操作prototype
// 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; } }
-
使用extend继承
// bad const inherits = require(\'inherits\'); function PeekableQueue(contents) { Queue.apply(this, contents); } inherits(PeekableQueue, Queue); PeekableQueue.prototype.peek = function() { return this._queue[0]; } // good class PeekableQueue extends Queue { peek() { return this._queue[0]; } }
-
不要使用通配符import
// bad import * as AirbnbStyleGuide from \'./AirbnbStyleGuide\'; // good import AirbnbStyleGuide from \'./AirbnbStyleGuide\';
-
不要在import中直接export
// bad // filename es6.js export { es6 as default } from \'./airbnbStyleGuide\'; // good // filename es6.js import { es6 } from \'./AirbnbStyleGuide\'; export default es6;
-
使用高阶函数(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;
-
访问对象属性使用‘.’,通过变量访问属性时使用中括号‘[]’
const luke = { jedi: true, age: 28, }; // bad const isJedi = luke[\'jedi\']; // good const isJedi = luke.jedi; function getProp(prop) { return luke[prop]; } const isJedi = getProp(\'jedi\');
-
将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;
-
优先使用 === 和 !== 而不是 == 和 !=.
-
条件表达式里面的值使用简写的方式
// bad if (name !== \'\') { // ...stuff... } // good if (name) { // ...stuff... } // bad if (collection.length > 0) { // ...stuff... } // good if (collection.length) { // ...stuff... }
注意:条件表达式例如 if 语句通过抽象方法 ToBoolean 强制计算它们的表达式并且总是遵守下面的规则:
- 对象:true
- Undefined:false
- Null :false
- 布尔值 :布尔的值
- 数字 :+0、-0、或 NaN 算为 false, 否则为 true
- 字符串:如果是空字符串 \'\' 为 false,否则为 true
- 数组:true(包括空数组 [] )
-
多行代码使用大括号包裹
// bad if (test) return false; function() { <
以上是关于eslint推荐编码规范和airbnb推荐编码规范的主要内容,如果未能解决你的问题,请参考以下文章