JS 规范

MuYan2022-04-15规范规范

JS 规范

缩进

使用 tab 缩进(2 个空格)

if (x < y) {
  x += 10;
} else {
  x += 1;
}

变量声明

一个函数作用域中所有的变量声明尽量提到函数首部。优先使用块级变量letconst,如无需修改的常量使用const

单行长度

单行长度不得超过 100,超过部分需要换行

分号

统一要加分号。

空格

  • 三元运算符'?:'前后
  • 逗号后必须要有空格
  • 代码块'{'前
  • 下列关键字前:else, while, catch, finally
  • 下列关键字后:if, else, for, while, do, switch, case, try,catch, finally, with, return, typeof
  • 单行注释'//'后(若单行注释和代码同行,则'//'前也需要),多行注释'*'后
  • 对象的属性值前
  • for 循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格
  • 无论是函数声明还是函数表达式,'{'前一定要有空格
  • 函数的参数之间

例:

// not good
var a = {
  b: 1,
};
// good
var a = {
  b: 1,
};
// not good
++x;
y++;
z = x ? 1 : 2;
// good
++x;
y++;
z = x ? 1 : 2;
// not good
var a = [1, 2];
// good
var a = [1, 2];
// good
var doSomething = function(a, b, c) {
  // do something
};
// good
doSomething(item);
// not good
for (let i = 0; i < 6; i++) {
  x++;
}
// good
for (let i = 0; i < 6; i++) {
  x++;
}

命名

普命名

普通命名采用小驼峰式命名

let userName = "jack";

复数命名

命名是复数的时候需要加 s,比如说我想声明一个数组,表示很多人的名字

let names = new Array();

常量命名

每个常量都需命名,这样更利于别人读懂含义

// good
const COL_NUM = 10;
let row = Math.ceil(num / COL_NUM);
// bad
let row = Math.ceil(num / 10);

类命名

类命名一律采用PascalCase命名风格

class Test {}

语义化

命名需要符合语义化,如果函数命名,可以采用加上动词前缀:

  • can 判断是否可执行某个动作
  • has 判断是否含有某个值
  • is 判断是否为某个值
  • get 获取某个值
  • set 设置某个值
//是否可阅读
function canRead(){
   return true;
}
//获取姓名
function getName{
   return this.name
}

注释

单行注释

  • 注释单独一行的情况下,注释的//后面要跟一个空格
  • 一律在被注释对象上方进行注释
// good
// 调用函数
foo();
// bad
let maxCount = 10; //这是一个变量

多行注释

多行注释建议在以下几种情况使用:

  • 难于理解的代码段
  • 可能存在错误的代码段
  • 业务逻辑强相关的代码
/** 类描述 */
export default class Test {
  /** 成员变量描述 */
  testValue = true;

  /** 方法描述
   * @param {String} a 参数描述
   * @return {Number} 返回值描述
   */
  test(a) {
    return this.testValue;
  }
}

复杂度

不允许存在多层嵌套的条件判断和循环(最多三层)(重点强调 ⭐) 条件判断能使用三目运算符和逻辑运算符解决的,就不要使用条件判断,但是谨记不要写太长的三目运算符

// bad
if (x === 10) {
  return "valid";
} else {
  return "invalid";
}
// good
return x === 10 ? "valid" : "invalid";

// bad
if (!x) {
  if (!y) {
    x = 1;
  } else {
    x = y;
  }
}

// good
x = x || y || 1;

字符串

统一使用单引号而不是双引号

// bad
const name = "jack";
// good
const name = "jack";

用字符串模板而不是 '+' 来拼接字符串

// bad
function sayHi(name) {
  return "How are you, " + name + "?";
}

// good
function sayHi(name) {
  return `How are you, ${name}?`;
}

数组

用字面量赋值

// bad
const items = new Array();
// good
const items = [];

用扩展运算符做数组浅拷贝

// bad
let arr = [1, 2, 3];
const len = arr.length;
const copyArr = [];
for (let i = 0; i < len; i += 1) {
  copyArr[i] = arr[i];
}
// good
const copyArr = [...arr];

用 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);

使用数组解构

const arr = [1, 2, 3, 4];
// bad
const first = arr[0];
const second = arr[1];
// good
const [first, second] = arr;

对象

创建对象和数组推荐使用字面量,因为这不仅是性能最优也有助于节省代码量。

// good
let obj = {
  name: "Tom",
  age: 15,
  sex: "男",
};
// bad
let obj = {};
obj.name = "Tom";
obj.age = 15;
obj.sex = "男";

ES6 使用属性值缩写

const lukeSkywalker = "Luke Skywalker";
// bad
const obj = {
  lukeSkywalker: lukeSkywalker,
};
// good
const obj = {
  lukeSkywalker,
};

将属性的缩写放在对象声明的开头

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,
};

对象浅拷贝时,更推荐使用扩展运算符 ...,而不是 Object.assign。解构赋值获取对象指定的几个属性时,推荐用 rest 运算符,也是 ...。

// very bad
const original = { a: 1, b: 2 };
const copy = Object.assign(original, { c: 3 });
delete copy.a; //  改变了 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, ...noA } = copy; // noA => { b: 2, c: 3 }

函数

函数参数使用默认值替代使用条件语句进行赋值。

// good
function createMicrobrewery(name = 'Jack') {
   ...
}
// bad
function createMicrobrewery(name) {
  const userNameName = name || 'Jack'
   ...
}
复制代码

函数参数使用结构语法,函数参数越少越好,如果参数超过两个,要使用 ES6 的解构语法,不用考虑参数的顺序。

// good
function createMenu({ title, body, buttonText, cancellable }) {
   ...
}
createMenu({
  title: 'Foo',
  body: 'Bar',
  buttonText: 'Baz',
  cancellable: true,
})
// bad
function createMenu(title, body, buttonText, cancellable) {
  // ...
}

优先使用 rest 语法...,而不是 arguments

// bad
function concatenateAll() {
  const args = Array.prototype.slice.call(arguments);
  return args.join("");
}
// good
function concatenateAll(...args) {
  return args.join("");
}

把默认参数赋值放在最后

// bad
function handleThings(opts = {}, name) {
  // ...
}
// good
function handleThings(name, opts = {}) {
  // ...
}

尽量使用箭头函数

// bad
[1, 2, 3]
  .map(function(x) {
    const y = x + 1;
    return x * y;
  })
  [
    // good
    (1, 2, 3)
  ].map((x) => {
    const y = x + 1;
    return x * y;
  });

模块

在非标准模块系统上使用(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;

一个入口只 import 一次

// bad
import foo from "foo";
// … some other imports … //
import { named1, named2 } from "foo";
// good
import foo, { named1, named2 } from "foo";

在只有一个导出的模块里,用 export default 更好

// bad
export function foo() {}
// good
export default function foo() {
上次更新 2026/6/23 11:49:15
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8