Skip to content

前端JS规范

变量

命名方式:小驼峰

命名规范:前缀名词

js
// bad
let setCount = 10

// good
let maxCount = 10

常量

命名方式:全部大写

命名规范:多个单词时使用分隔符_

js
// bad
const serverErrorCode = {
    success: 200,
    repeat: 444
}

// good
const SERVER_ERROR_CODE = {
    SUCCESS: 200,
    REPEAT: 444
}

函数名

命名方式:小驼峰

命名规范:前缀动词

js
// bad
function wordClass() {}

// good
function saveWordClass() {}

常用动词:can、has、is、load、get、set

类名

命名方式:大驼峰

命名规范:前缀名词

js
// bad
class person {}

// good
class Person {}

注释

单行

js
// 单行注释,注意前面的空格
let maxCount = 123

多行

js
/**
 * 多行注释
 * /

函数注释

js
/**
 * 函数描述
 *
 * @param {string} p1 参数1的说明
 * @param {string} p2 参数2的说明,比较长
 *     那就换行了.
 * @param {number=} p3 参数3的说明(可选)
 * @return {Object} 返回值描述
 */
function foo(p1, p2, p3) {
    var p3 = p3 || 10;
    return {
        p1: p1,
        p2: p2,
        p3: p3
    };
}

函数

函数行数

  • [建议] 一个函数的长度控制在 50 行以内。

将过多的逻辑单元混在一个大函数中,易导致难以维护。一个清晰易懂的函数应该完成单一的逻辑单元。复杂的操作应进一步抽取,通过函数的调用来体现流程。

特定算法等不可分割的逻辑允许例外。

参数设计

  • [建议] 一个函数的参数控制在 6 个以内。

除去不定长参数以外,函数具备不同逻辑意义的参数建议控制在 6 个以内,过多参数会导致维护难度增大。

  • [建议] 通过 options 参数传递非数据输入型参数。

这种模式有几个显著的优势:

  • 当配置项有增长时,无需无休止地增加参数个数,不会出现 removeElement(element, true, false, false, 3) 这样难以理解的调用代码。
  • 当部分配置参数可选时,多个参数的形式非常难处理重载逻辑,而使用一个 options 对象只需判断属性是否存在,实现得以简化。

空格(prettier自动)

  • 二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格

    js
    var a = !arr.length;
    a++;
    a = b + c;
  • 用作代码块起始的左花括号 { 前必须有一个空格

    js
    if (condition) {
    }
  • if / else / for / while / function / switch / do / try / catch / finally 关键字后,必须有一个空格

  • 在对象创建时,属性中的 : 之后必须有空格,: 之前不允许有空格

    js
    var obj = {
        a: 1,
        b: 2,
        c: 3
    };
  • 函数声明、具名函数表达式、函数调用中,函数名和 ( 之间不允许有空格。

    js
    // good
    function funcName() {
    }
  • 在函数调用、函数声明、括号表达式、属性访问、if / for / while / switch / catch 等语句中,()[] 内紧贴括号部分不允许有空格。

    js
    // good
    callFunc(param1, param2, param3)
  • 单行声明的数组与对象,如果包含元素,{}[] 内紧贴括号部分不允许包含空格。

    声明包含元素的数组与对象,只有当内部元素的形式较为简单时,才允许写在一行。元素复杂的情况,还是应该换行书写。

    js
    // good
    var arr1 = []
    var arr2 = [1, 2, 3]
    var obj1 = {}
    var obj2 = {name: 'obj'}
    var obj3 = {
        name: 'obj',
        age: 20,
        sex: 1
    }

括号

下列关键字后必须有大括号(即使代码块的内容只有一行):if, else, for, while, do, switch, try, catch, finally, with

减少嵌套

确定条件不允许时,尽早返回。经典使用场景:校验数据

js
// bad
if (condition1) {
    if (condition2) {
        ...
    }
}

// good
if (!condition1) return
if (!condition2) return
...

减少特定标记值

使用常量进行自解释

js
// bad
type: 1 // 1代表新增  2代表修改

// good
const MODIFY_TYPE = {
    ADD: 1,
    EDIT: 2
}

type: MODIFY_TYPE.ADD

表达式

尽可能简洁表达式

js
// bad
if (name === ''){}
if (collection.length > 0){}
if (notTrue === false){}

// good
if (!name) {}
if (collection.length){}
if (notTrue){}

分支较多处理

对于相同变量或表达式的多值条件,用switch代替if

js
// bad
let type = typeof variable
if (type === 'object') {
    // ......
}
else if (type === 'number' || type === 'boolean' || type === 'string') {
    // ......
}

// good
switch (typeof variable) {
    case 'object':
        // ......
        break
    case 'number':
    case 'boolean':
    case 'string':
        // ......
        break
}

使用变量名自解释

逻辑复杂时,建议使用变量名自解释,而不是晦涩难懂的简写。

js
// bad
function(value) {
    return !helpers.req(value) || this.entity.entVocabularyEntries.filter(item => item.vocabularyEntryName === value).length < 2
}

// good
function(value) {
    let entVocabularyList = this.entity.entVocabularyEntries
    let repeatCount = entVocabularyList.filter(item => item.vocabularyEntryName === value).length
    return !helpers.req(value) || repeatCount < 2
}

使用函数名自解释

遵循单一职责的基础上,可以把逻辑隐藏在函数中,同时使用准确的函数名自解释。

js
// bad
if (modifyType === MODIFY_TYPE.ADD) {
    batchVariableAPI(data).then(() => {
        this.closeModal()
        this.$toast.show('添加变量成功')
    })
} else {
  updateVariableAPI(data).then(() => {
        this.closeModal()
        this.$toast.show('修改变量成功')
    })
}

// good
modifyType === MODIFY_TYPE.ADDthis._insertVariable(data) : this._updateVariable(data)

_insertVariable() {
    batchVariableAPI(data).then(() => this._successOperation('添加变量成功'))
}

_updateVariable() {
    updateVariableAPI(data).then(() => this._successOperation('修改变量成功'))
}

_successOperation(toastMsg) {
    this.closeModal()
    this.$toast.show(toastMsg)
}

杂项

  • 用'===', '!=='代替'==', '!='
  • 不要在内置对象的原型上添加方法,如Array, Date
  • 不要声明了变量却不使用
  • 变量不要先使用后声明
  • 不要在循环内部声明函数
  • 对上下文this的引用只能使用'_this', 'that', 'self'其中一个来命名

工具: prettierrc格式化 + eslint校验

  • 自动格式化
  • 2个缩进
  • 最外层使用单引号
  • 方法if / else / for / while / function / switch / do / try / catch / finally 关键字后有一个空格
  • 自动省略分号

参考链接

百度JS规范