js书写规范
参考文献:https://github.com/airbnb/javascript
1. 使用 const 与 let 代替 var (const / let)
1.1、常量使用 const 定义,避免使用 var 定义:这样可以确保无法重新分配,这可能导致错误并难以理解代码。
// bad var a = 1; var b = 2; // good const a = 1; const b = 2;
1.2、使用 let 代替 var 定义变量:let是像var这样的块作用域而不是函数作用域。
// bad var count = 1; if (true) { count += 1; } // good, use the let. let count = 1; if (true) { count += 1; }
注意: let 和 const 都是块作用域
2. 对象(Object)
2.1 使用文字形式创建对象
// bad const item = new Object(); // good const item = {};
2.2、使用对象方法的简写
// bad const atom = { value: 1, addValue: function (value) { return atom.value + value; }, }; // good const atom = { value: 1, addValue(value) { return atom.value + value; }, };
2.3、使用属性速记:因为简短而具有描述性
const lukeSkywalker = 'Luke Skywalker'; // bad const obj = { lukeSkywalker: lukeSkywalker, }; // good const obj = { lukeSkywalker, };
2.4:、在对象声明的开头对速记属性进行分组。
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、仅引用无效标识符的属性:更容易阅读,因为他改善了语法突出显示的功能,并且还易于通过许多JS引擎进行优化。
// bad const bad = { 'foo': 3, 'bar': 4, 'data-blah': 5, }; // good const good = { foo: 3, bar: 4, 'data-blah': 5, };
3. 数组(Arrays)
3.1、应尽量使用文字语法创建数组(如果有必要,特殊情况除外,如:new Array(10).fill(true))
// bad const items = new Array(); // good const items = [];
3.2、使用 spread(‘...’)操作符copy数组
// bad const len = items.length; const itemsCopy = []; let i; for (i = 0; i < len; i += 1) { itemsCopy[i] = items[i]; } // good const itemsCopy = [...items];
3.3、使用 spreads(‘...’)操作符将可迭代的对象转化为数组,而不是使用 Array.from([])
const foo = document.querySelectorAll('.foo'); // good const nodes = Array.from(foo); // best const nodes = [...foo];
3.4、Array.from 用于将类似数组的对象转换为数组
const arrLike = { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 }; // bad const arr = Array.prototype.slice.call(arrLike); // good const arr = Array.from(arrLike);
3.5、使用 Array.from 而不是spread ...来映射可迭代对象,因为它避免了创建中间数组。
// bad const baz = [...foo].map(bar); // good const baz = Array.from(foo, bar);
3.6、如果数组有多行,则在打开和关闭数组括号之前使用换行符(因为一行的宽度是有限的,而数列的高度是无限的,这样有利于代码的阅读)
// bad const arr = [ [0, 1], [2, 3], [4, 5], ]; const objectInArray = [{ id: 1, }, { id: 2, }]; const numberInArray = [ 1, 2, ]; // good const arr = [[0, 1], [2, 3], [4, 5]]; const objectInArray = [ { id: 1, }, { id: 2, }, ]; const numberInArray = [ 1, 2, ];
3.7、在数组方法回调中使用return语句。如果函数主体由一个返回单一的表达式的语句组成,则可以省略 return
// good [1, 2, 3].map((x) => { const y = x + 1; return x * y; }); // good [1, 2, 3].map((x) => x + 1); inbox.filter((msg) => { const { subject, author } = msg; if (subject === 'Mockingbird') { return author === 'Harper Lee'; } else { return false; } }); // good inbox.filter((msg) => { const { subject, author } = msg; if (subject === 'Mockingbird') { return author === 'Harper Lee'; } return false; });
4. 结构
4.1、访问和使用对象的多个属性时,请使用对象分解:解构可避免您为这些属性创建临时引用,打包时能够优化代码
// bad function getFullName(user) { const firstName = user.firstName; const lastName = user.lastName; return `${firstName} ${lastName}`; } // good function getFullName(user) { const { firstName, lastName } = user; return `${firstName} ${lastName}`; } // best function getFullName({ firstName, lastName }) { return `${firstName} ${lastName}`; }
4.2、使用数组解构
const arr = [1, 2, 3, 4]; // bad const first = arr[0]; const second = arr[1]; // good const [first, second] = arr;
4.3、对多个返回值对象解构时应当使用对象,而不是数组
// bad function processInput(input) { // then a miracle occurs return [left, right, top, bottom]; } // 调用者需要按照顺序调用 const [left, __, top] = processInput(input); // good function processInput(input) { // then a miracle occurs return { left, right, top, bottom }; } // 调用者可以选择需要的数据 const { left, top } = processInput(input);
5. 字符串处理
5.1、字符串应当使用单引号
// bad const name = "Capt. Janeway"; // bad - 模板字符串中应当包含插值 const name = `Capt. Janeway`; // good const name = 'Capt. Janeway';
5.2、字符串不应使用字符串连接跨多行写入:字符串损坏很难使用,并且使代码的可搜索性降低。
// 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.';
5.3、代码构建字符串时,应当使用模板字符串,而不是使用 '+'连接符:模板字符语法更精简易懂并有适当的换行和插值功能
const str1 = '123' const str2 = '234' // bad const newStr = str1 + str2 //good const newStr = `${str1}${str2}`
5.4、在不必要的情况下,不要使用转义字符与eval()方法
6. 方法(Function)
6.1、使用命名函数表达式而不是函数声明:这样更利于进行模块化开发
// bad function foo() { // ... } // bad const foo = function () { // ... }; // good // lexical name distinguished from the variable-referenced invocation(s) const short = function longUniqueMoreDescriptiveLexicalFoo() { // ... };
6.2、不要在非功能块(如:while、if 等)中声明方法
6.3、永远不要使用 arguments 作为函数参数,或者通过arguments的获取参数
// bad function concatenateAll() {
// 把调用方法的参数截取出来 const args = Array.prototype.slice.call(arguments); return args.join(''); } // good function concatenateAll(...args) { return args.join(''); }
6.4、使用默认参数语法,而不是对函数参数进行修正,并且应当将函数的默认值参数放在函数的最后
// really bad function handleThings(opts) { // 我们不能修改函数的参数 // 如果 opts = false,那么则有可能变为 {} // 这样做可能出现一些问题 opts = opts || {}; // ... } // still bad function handleThings(opts) { if (opts === void 0) { opts = {}; } // ... } // good 因为opts为默认值参数,应放在函数参数的最后 function handleThings(id, opts = {}) { // ... }
6.5、不应该对函数的参数进行处理,这样将难以理解
var b = 1; // bad function count(a = b++) { console.log(a); } count(); // 1 count(); // 2
6.7、不要更改和重新分配函数的参数值,若需要,应当建立副本进行变更,否则将可能出现错误
6.8、最好使用点差运算符...来调用可变参数函数。这样代码更干净
// bad const x = [1, 2, 3, 4, 5]; console.log.apply(console, x); // good const x = [1, 2, 3, 4, 5]; console.log(...x);
6.9、若有多行或函数参数有多个时应当提行
// bad function foo(bar, baz, quux) { // ... } // good function foo( bar, baz, quux, ) { // ... } // bad console.log(foo, bar, baz); // good console.log( foo, bar, baz, );
7. 箭头函数
7.1、当您必须使用匿名函数时(如传递内联回调时),请使用箭头函数符号。
7.2、使用匿名函数时,及时只有一个参数,也应当使用 ( ) 将参数括起来
7.3、如果函数主体由单个语句组成时,请省略花括号并使用隐式返回。否则,请保留括号并使用return语句
// bad(匿名函数使用箭头函数) [1, 2, 3].filter((item) => { return item === 1 || item === 2 }) // good 表达式有多行时应当换行 [1, 2, 3].filter((item) => (
item === 2 ||
item === 1
))
8. js类与构造函数参考原文献
9. 模块
9.1、使用 improt / export 导出和导入模块:模块就是未来
// bad const AirbnbStyleGuide = require('./AirbnbStyleGuide'); module.exports = AirbnbStyleGuide.es6; // ok import AirbnbStyleGuide from './AirbnbStyleGuide'; export default AirbnbStyleGuide.es6; // best import { es6 } from './AirbnbStyleGuide'; export default es6;
9.2、不要使用 * as xxx 并且不要在导入中导出 这样可以保证有单一的导出
// bad import * as AirbnbStyleGuide from './AirbnbStyleGuide'; // good import AirbnbStyleGuide from './AirbnbStyleGuide';
// bad
// filename es6.js
export { es6 as default } from './AirbnbStyleGuide';
// good
// filename es6.js
import { es6 } from './AirbnbStyleGuide';
export default es6;
9.3、仅从一个位置的路径导入。
// bad import foo from 'foo'; // … some other imports … // import { named1, named2 } from 'foo'; // good import foo, { named1, named2 } from 'foo'; // good import foo, { named1, named2, } from 'foo';
9.4、通常只应该导出常量(也就是 const 定义的常量)
9.5、如果一个模块只有单一的导出,应当首选 exprot default {}, 而不是 export const foo = {}
9.6、应该将所有的导出放置文件最顶部
9.7、多行导入应当换行,每行只显示一个导入
// bad import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path'; // good import { longNameA, longNameB, longNameC, longNameD, longNameE, } from 'path';
10. 属性
10.1、访问属性时,在非必要(比如 变量 访问属性时)的情况下应使用点符号
const luke = { jedi: true, age: 28, }; // bad const isJedi = luke['jedi']; // good const isJedi = luke.jedi;
11. 变量 与 常量(let 与 const)
11.1、始终使用const或let来声明变量,不这样做将导致全局变量,污染全局名称空间
// bad superPower = new SuperPower(); // good const superPower = new SuperPower();
11.2、 对每个变量或赋值使用一个const或let声明。
// bad const items = getItems(), goSportsTeam = true, dragonball = 'z'; // bad // (compare to above, and try to spot the mistake) const items = getItems(), goSportsTeam = true; dragonball = 'z'; // good const items = getItems(); const goSportsTeam = true; const dragonball = 'z';
11.3、对所有const进行分组,然后对所有let进行分组。(统一将 const 放在 let 的前面)
11.4、在需要它们的地方分配变量,但是将它们放在合理的位置。
// bad - unnecessary function call function checkName(hasName) { const name = getName(); if (hasName === 'test') { return false; } if (name === 'test') { this.setName(''); return false; } return name; } // good function checkName(hasName) { if (hasName === 'test') { return false; } const name = getName(); if (name === 'test') { this.setName(''); return false; } return name; }
11.5、不要链接变量分配:链接变量分配会创建隐式全局变量。
// bad let a = b = c = 1; // good let a = 1; let b = a; let c = a;
11.6、避免使用 ++ 或 --,使用 += 或 -= 代替(eslint规范)
11.7、在 = 后边应避免换行,若需要请使用 ( ) 将内容括起来
11.8、全局常量应当全部大写
12. 运算符
12.1、 == 与 != 应使用 === 与 !== 替代
12.2、注意 if 判断,因遵循如下规则
· object 为 true
· undefined的结果为false
· Null 的结果为 false
· Booleans 的结果为 boolean值
· Numbers +0, -0,NaN 为false,否则为true
· 如果为空字符串“”,则字符串的计算结果为false,否则为true
13、块
13.1、将括号与所有多行块一起使用。
// bad if (test) return false; // good if (test) return false; // good if (test) { return false; } // bad function foo() { return false; } // good function bar() { return false; }
13.2、如果您将多行代码块与if和else一起使用,请将else与if块的右括号放在同一行。
// bad if (test) { thing1(); } else { thing3(); } // good if (test) { thing1(); } else { thing3(); }
13.3、如果if块始终执行return语句,则随后的else块是不必要的。
// bad function foo() { if (x) { return x; } else { return y; } } // good function foo() { if (x) { return x; }
return y; }
14. 空格(具体遵循eslint规范)
14.1、始终使用 2 个空格作为块之间的间距
14.2、在前括号【{ }, ( )】之前放置1个空格
// bad function test(){ console.log('test'); } // good function test() { console.log('test'); }
14.3、在控制语句中的左括号前放置1个空格(如果,则等)。在函数调用和声明中,参数列表和函数名称之间不能留空格。
// bad if(isJedi) { fight (); } // good if (isJedi) { fight(); } // bad function fight () { console.log ('Swooosh!'); } // good function fight() { console.log('Swooosh!'); }
14.4、 用空格隔开运算符。
// bad const sum=1+23+5 // gold const sum = 1 + 2 +5
14.5、 在块之后和下一条语句之前保留空白行。// bad
const arr = [ function foo() { }, function bar() { }, ]; return arr; // good const arr = [
function foo() { }, function bar() { }, ]; return arr;
14.6、不要在括号内添加空格,不要在方括号内添加空格
// bad function bar( foo ) { return foo; } // good function bar(foo) { return foo; }
// bad
const foo = [ 1, 2, 3 ];
console.log(foo[ 0 ]);
// good
const foo = [1, 2, 3];
console.log(foo[0]);
14.7、在花括号内添加空格。
// bad const foo = {clark: 'kent'}; // good const foo = { clark: 'kent' };
语句后边的分号、逗号遵循 eslint(常用通用配置:standard) 即可