本文参照链接文章: https://blog.csdn.net/yuanwenyan/article/details/78653606
1,基本规范
1.0 基本命名规范
js的js文件命名,class组件命名:大驼峰AaBbCc
js的函数名,方法,参数,变量:使用小驼峰aaBbCc
js的文件夹命名:aa-bb-cc
1.1 基本类型:在栈内存中,操作和保存在变量的实际的值,直接存取
5种基本类型:字符,数值 ,布尔类型 ,null ,undefined
const foo = 1;
let bar = foo;bar = 9;
console.log(foo, bar); // => 1, 9
1.2 引用类型:在堆内存中,值保存在内存中,js不允许直接访问内存,通过引用的方式存取。
例如对象 数组 函数等
const foo = [1, 2];
const bar = foo;bar[0] = 9;
console.log(foo[0], bar[0]); // => 9,9
2,引用
2.1 对所有的引用类型使用 const ; 不要使用 var 。
为什么?这确保你无法对引用类型重新赋值,也不会导致出现 bug 或难以理解。
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
2.2 如果你一定需要可变动的引用,使用 let 替代 var 。
为什么?因为 let 是块级作用域,而 var 是函数作用域。
// bad
var count = 1;
if(true){
count += 1;
}// good, use the let
let count = 1;
if(true){
count += 1;
}
2.3 注意 let 和 const 都是块级作用域。
{
let a = 1;
const b = 1;
}
console.log(a);//ReferenceError
console.log(b);//ReferenceError
3,对象
3.1 使用字面值创建对象。
// bad
const item = new Object();// good
const item = {};
3.2 如果你的代码在浏览器环境下执行,别使用 保留字 作为键值。但是在ES6模块或服务器端使用则没有问题。
// bad
const person = {
default: { name: ‘peter’ },
private: true
}// good
const person = {
defaults: { name: ‘peter’ },
hidden: true
}
3.3 使用同义字替换需要使用的保留字。
// bad
const person = {
class: ‘info’
}// bad
const person = {
kclass: ‘info’
}// good
const person = {
type: ‘info’
}
3.4 创建有动态属性名的对象时,使用可被计算的属性名称。
为什么?因为这样让你在一个地方定义所有的对象属性。
function getKey(k){
return a key named ${k};
}// bad
const obj = {
id: 5,
name: ‘peter’
}
obj[getKey[‘enabled’]] = true;// good
const obj = {
id: 5,
name: ‘peter’,
[getKey[‘enabled’]]: true;
}
3.5 使用对象方法的简写。
// bad
const atom = {
value: 1,addValue: function(value){
return atom.value + value;
}
}// good
const atom = {
value: 1,addValue(value){
return atom.value + value;
}
}
3.6 使用对象属性值的简写:key和value相等
const name = ‘peter’;
// bad
const obj = {
name: name
}// good
const obj = {
name
}
3.7 在对象属性声明前把简写的属性分组。
const name = ‘name’;
const age = ‘age’;// bad
const obj = {
name,
sex: ‘男’,
age,
height: ‘170’
}// good
const obj = {
name,
age,
sex: ‘男’,
height: ‘170’
}
4,数组
4.1 使用字面值创建数组。
// bad
const items = new Array();// good
const items = [];
4.2 向数组添加元素时使用 Array#push 替代直接赋值。
const names = [];
// bad
names[0] = ‘peter’;// good
names.push(‘peter’);
4.3 使用拓展运算符 … 复制数组。
const items = [‘xiaoxin’, ‘xiaoqiang’, ‘xiaowanzi’];
// bad
const itemsCopy = [];
for(let i = 0; i < items.length; i++){
itemsCopy[i] = items[i];
}// good
const itemsCopy = […items];
5,解构
5.1 使用解构存取和使用多属性对象。
为什么?因为解构能减少临时引用属性。
// bad
function getFullName(user){
const fileName = 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}
}
5.2 对数组使用解构赋值。
cosnt arr = [1,2,3,4];
// bad
const first = arr[0];
const second = arr[1];//good
const [first, second] = arr;
6,字符串
6.1 字符串使用单引号 ” 。
// bad
const name = “peter”;// good
const name = ‘peter’;
6.2 字符串超过80个字节使用字符串连接号连接。
// bad
const info = ‘American colleges and universities awarded about one million seven hundred thousand bachelor\’s degrees in the school year ending in twenty ten.’;// good
const info = ‘American colleges and universities awarded about one million seven hundred thousand bachelor\’s ’
+ ‘degrees in the school year ending in twenty ten.’
6.3 程序化生成字符串时,使用模板字符串替代字符串连接。
// bad
function sayHi(name){
return ‘How are you, ’ + name + ‘?’;
}// good
function sayHi(name){
return How are you ${name}?
}
7,函数
7.1 使用函数声明代替函数表达式。
为什么?因为函数声明是可命名的,所以他们在调用栈中更容易被识别。此外,函数声明会把整个函数提升,而函数表达式只会把函数的引用变量名提升。
// bad
const foo = function(){
}// good
function foo(){
}
7.2 函数表达式:
//立即调用的函数表达式
(() => {
console.log(‘Welcome to my home!’);
})()
7.3 函数声明
永远不要在一个非函数代码块( if, while 等)中声明一个函数,把那个函数赋给一个变量。浏览器允许你这么做,但它们的解析表现不一致。
7.4 直接给函数的参数指定默认值,不要使用一个变化的函数参数。
// bad
function handleThings(opts){
opts = opts || {};
}// still bad
function handleThings(opt){
if(opts === void 0){
opts = {};
}
}// good
function handleThings(opts = {}){}
8,箭头函数
8.1 当你必须使用函数表达式(或传递一个匿名函数)时,使用箭头函数符号。
为什么?因为箭头函数创造了新的 this 执行环境,通常情况下都能满足你的需求,而且这样的写法更为简洁。
// bad
[1, 2, 3].map(function (x) {
return x * x;
})// good
[1, 2, 3].map(x => {
return x * x;
})
8.2 如果一个函数适合用一行写出并且只有一个参数,那就把花括号、圆括号和 return 都省略掉。如果不是,那就不要省略。
// good
[1, 2, 3].map(x => x * x);// good
[1, 2, 3].map((total, x) => {
return total + x;
})
9,构造函数
9.1 总是使用 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;
}
}
9.2 使用 extends 继承。
为什么?因为 extends 是一个内建的原型继承方法并且不会破坏 instanceof 。
// 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];
}
}
9.3 方法可以返回 this 来帮助链式调用。
// bad
Jedi.prototype.jump = function() {
this.jumping = true;
return true;
};Jedi.prototype.setHeight = function(height) {
this.height = height;
};const luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20); // => undefined// good
class Jedi {
jump() {
this.jumping = true;
return this;
}setHeight(height) {
this.height = height;
return this;
}
}const luke = new Jedi();
luke.jump().setHeight(20);
9.4 可以写一个自定义的 toString() 方法,但要确保它能正常运行并且不会引起副作用。
class Jedi {
constructor(options = {}) {
this.name = options.name || ‘no name’;
}getName() {
return this.name;
}toString() {
return `Jedi - ${this.getName()}`;
}
}
10,模块
10.1 总是使用(import / 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;
10.2 不要使用通配符 import。
为什么?这样能确保你只有一个默认的 export。
// bad
import * as AirbnbStyleGuide from ‘./AirbnbStyleGuide’;// good
import AirbnbStyleGuide from ‘./AirbnbStyleGuide’;
10.3 不要从 import 中直接 export。
// bad
// filename es6.js
export { es6 as default } from ‘./airbnbStyleGuide’;// good
// filename es6.js
import { es6 } from ‘./AirbnbStyleGuide’;
export default es6;
11,属性
11.1 使用 . 来访问对象的属性。
const student = {
name: ‘peter’,
age: 27
}// bad
const person = student[‘name’];// good
const person = student.name;
11.2 当通过变量访问属性时使用中括号 [].
const student = {
name: ‘peter’,
age: 27
}function getName(name){
return student[name];
}const name = getName(‘name’);
12,变量
12.1 一直使用 const 来声明变量,如果不这样就会产生全局变量。
// bad
name = ‘peter’;age = 27;
// good
const name = ‘peter’;const age = 27;
12.2 在你需要的地方给变量赋值,但请他它们放在一个合理的位置。
// bad
function(hasName) {
const name = getName();if (!hasName) {
return false;
}this.setFirstName(name);
return true;
}// good
function(hasName) {
if (!hasName) {
return false;
}const name = getName();
this.setFirstName(name);return true;
}
13,比较运算符 & 等号
13.1 优先使用 === 和 !== 而不是 == 和 != 。
13.2 使用简写。
// bad
if (name !== ”) {
}// good
if (name) {
}// bad
if (name.length > 0) {
}// good
if (name.length) {
}
14,逗号
14.1 行首逗号,不需要。
// bad
const story = [
once
, upon
, aTime
];// good
const story = [
once,
upon,
aTime,
];// bad
const hero = {
firstName: ‘Ada’
, lastName: ‘Lovelace’
, birthYear: 1815
, superPower: ‘computers’
};// good
const hero = {
firstName: ‘Ada’,
lastName: ‘Lovelace’,
birthYear: 1815,
superPower: ‘computers’,
};
14.2 行尾逗号,需要。
为什么? 这会让 git diff 更干净。另外,像 babel 这样的转译器会移除结尾多于的逗号,也就是说你不必担心老旧浏览器的结尾逗号问题。
// bad
const student = {
name: ‘peter’,
age: 27
}// good
const student = {
name: ‘peter’,
age: 27,
}
15,分号
15.1 使用分号
// bad
(function() {
const name = ‘Skywalker’
return name
})()// good
(() => {
const name = ‘Skywalker’;
return name;
})();// good (防止函数在两个 IIFE 合并时被当成一个参数)
;(() => {
const name = ‘Skywalker’;
return name;
})();
16,类型转换
16.1 在语句开始时执行类型转换。
// => this.reviewScore = 9;
// bad
const totalScore = this.reviewScore + ”;// good
const totalScore = String(this.reviewScore);
16.2 字符串
const inputValue = ‘4’;
// bad
const val = new Number(inputValue);// bad
const val = +inputValue;// bad
const val = inputValue >> 0;// bad
const val = parseInt(inputValue);// good
const val = Number(inputValue);// good
const val = parseInt(inputValue, 10);
16.3 对数字使用 parsetInt 转换,病带上类型转换的基数。
// good
/**
* 使用 parseInt 导致我的程序变慢,
* 改成使用位操作转换数字快多了。
*/
const val = inputValue >> 0;
16.4 布尔
const age = 0;
// bad
const hasAge = new Boolean(age);// good
const hasAge = Boolean(age);// good
const hasAge = !!age;
17,命名规则
17.1 避免单字母命名。命名应具备描述性。
// bad
function q() {
// …stuff…
}// good
function query() {
// ..stuff..
}
17.2 使用驼峰式命名对象、函数和实例。
// bad
const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}// good
const thisIsMyObject = {};
function thisIsMyFunction() {}
17.3 使用帕斯卡式命名构造函数或类。
// bad
function user(options) {
this.name = options.name;
}const bad = new user({
name: ‘nope’,
});// good
class User {
constructor(options) {
this.name = options.name;
}
}const good = new User({
name: ‘yup’,
});
17.4 使用下划线 _ 开头命名私有属性。
// bad
this.firstName = ‘Panda’;
this.firstName_ = ‘Panda’;// good
this._firstName = ‘Panda’;
17.5 别保存 this 的引用。使用箭头函数或 Function#bind。
// bad
function foo() {
const self = this;
return function() {
console.log(self);
};
}// bad
function foo() {
const that = this;
return function() {
console.log(that);
};
}// good
function foo() {
return () => {
console.log(this);
};
}
17.6 如果你的文件只输出一个类,那你的文件名必须和类名完全保持一致。
// file contents
class CheckBox {
// …
}
export default CheckBox;// in some other file
// bad
import CheckBox from ‘./checkBox’;// bad
import CheckBox from ‘./check_box’;// good
import CheckBox from ‘./CheckBox’;
17.7 当你导出默认的函数时使用驼峰式命名。你的文件名必须和函数名完全保持一致。
function makeStyleGuide() {
}export default makeStyleGuide;
17.8 当你导出单例、函数库、空对象时使用帕斯卡式命名。
const AirbnbStyleGuide = {
es6: {
}
};export default AirbnbStyleGuide;