美文网首页
js代码规范

js代码规范

作者: Mica_马超 | 来源:发表于2019-05-24 17:10 被阅读0次

    js代码规范

    文档

    JavaScript 文件使用无 BOM 的 UTF-8 编码。
    在文件结尾处,保留一个空行。
    使用 2 个空格做为一个缩进层级,不允许使用 4 个空格 或 tab 字符。
    每个独立语句结束后必须换行。每行不得超过 120 个字符。
    运算符处换行时,运算符必须在新行的行首。
    // good
    if (user.isAuthenticated()
        && user.isInRole('admin')
        && user.hasAuthority('add-admin')
        || user.hasAuthority('delete-admin')
    ) {
        // Code
    }
    
    var result = number1 + number2 + number3
        + number4 + number5;
    
    
    // bad
    if (user.isAuthenticated() &&
        user.isInRole('admin') &&
        user.hasAuthority('add-admin') ||
        user.hasAuthority('delete-admin')) {
        // Code
    }
    
    var result = number1 + number2 + number3 +
        number4 + number5;
    
    在函数声明、函数表达式、函数调用、对象创建、数组创建、for语句等场景中,不允许在 , 或 ; 前换行。
    // good
    var obj = {
      a: 1,
      b: 2,
      c: 3
    };
    
    foo(
      aVeryVeryLongArgument,
      anotherVeryLongArgument,
      callback
    );
    
    
    // bad
    var obj = {
      a: 1
      , b: 2
      , c: 3
    };
    
    foo(
      aVeryVeryLongArgument
      , anotherVeryLongArgument
      , callback
    );
    
    不同行为或逻辑的语句集,使用空行隔开,更易阅读。
    当参数过多时,将每个参数独立写在一行上,并将结束的右括号 ) 独立一行。所有参数必须增加一个缩进。
    foo(
      aVeryVeryLongArgument,
      anotherVeryLongArgument,
      callback
    );
    
    也可以按逻辑对参数进行组合。

    比如angularjs的服务注入,可以将框架提供的服务、自定义服务、常量、提供器分开。

    function run(
      $log, $rootScope, $cookies, // 框架内提供
      serverConfig, CONFIG,  // 提供器、常量
      common, sgCommon,  // 自定义服务
    );
    
    三元运算符由3部分组成,因此其换行应当根据每个部分的长度不同,形成不同的情况。
    var result = thisIsAVeryVeryLongCondition
        ? resultA : resultB;
    
    var result = condition
        ? thisIsAVeryVeryLongResult
        : resultB;
    
    对于 if...else...、try...catch...finally 等语句,推荐使用在 } 号后添加一个换行 的风格,使代码层次结构更清晰,阅读性更好。
    if (condition) {
        // some statements;
    }
    else {
        // some statements;
    }
    
    try {
        // some statements;
    }
    catch (ex) {
        // some statements;
    }
    
    不得省略语句结束的分号。
    在 if / else / for / do / while 语句中,即使只有一行,也不得省略块 {...}。
    // good
    if (condition) {
      callFunc();
    }
    
    // bad
    if (condition) callFunc()
    if (condition)
      callFunc()
    

    命名

    变量 使用 Camel命名法。
    var loadingModules = {};
    
    常量 使用 全部字母大写,单词间下划线分隔 的命名方式。
    var HTML_ENTITY = {};
    
    函数 使用 Camel命名法。
    function stringFormat(source) {
    }
    
    类 使用 Pascal命名法。
    function TextNode(options) {
    }
    
    枚举变量 使用 Pascal命名法,枚举的属性 使用 全部字母大写,单词间下划线分隔 的命名方式。
    var TargetState = {
        READING: 1,
        READED: 2,
        APPLIED: 3,
        READY: 4
    };
    
    命名空间 使用 Camel命名法。
    equipments.heavyWeapons = {};
    
    类名 使用 名词。
    函数名 使用 动宾短语。
    function getStyle(element) {
    }
    
    boolean 类型的变量使用 is 或 has 开头。
    Promise对象 用 动宾短语的进行时 表达。

    注释

    代码细节注释全部使用行注释,不可使用这样的/*...*/多行注释
    为了便于代码阅读和自文档化,以下内容必须包含以 /**...*/ 形式的块注释。
    • 文件
    • namespace
    • 函数或方法
    • 类属性
    • 事件
    • 全局变量
    • 常量
    注释中类型说明格式以{开始, 以}结束。

    常用类型如:{string}, {number}, {boolean}, {Object}, {Function}, {RegExp}, {Array}, {Date}。

    /**
     * 函数描述
     *
     * @param {string} p1 参数1的说明
     * @param {string} p2 参数2的说明,比较长
     *     那就换行了.
     * @param {number=} p3 参数3的说明(可选)
     * @return {Object} 返回值描述
     */
    
    类型定义 语法示例 解释
    String {string} --
    Number {number} --
    Boolean {boolean} --
    Object {Object} --
    Function {Function} --
    RegExp {RegExp} --
    Array {Array} --
    Date {Date} --
    单一类型集合 {Array.<string>} string 类型的数组
    多类型 {(number|boolean)} 可能是 number 类型, 也可能是 boolean 类型
    允许为null {?number} 可能是 number, 也可能是 null
    不允许为null {!Object} Object 类型, 但不是 null
    Function类型 {function(number, boolean)} 函数, 形参类型
    Function带返回值 {function(number, boolean):string} 函数, 形参, 返回值类型
    参数可选 @param {string=} name 可选参数, =为类型后缀
    可变参数 @param {...number} args 变长参数, ...为类型前缀
    任意类型 {*} 任意类型
    可选任意类型 @param {*=} name 可选参数,类型不限
    可变任意类型 @param {...*} args 变长参数,类型不限
    文件注释

    注释添加作者一项

    /**
     * @file Describe the file
     * @author xiaozhao@domain.com
     */
    
    命名空间注释
    /**
     * 描述
     * @namespace
     */
    var util = {};
    
    使用 @class 标记类或构造函数。
    /**
     * 描述
     *
     * @class
     */
    function Developer() {
        // constructor body
    }
    
    使用 @extends 标记类的继承信息。
    /**
     * 描述
     *
     * @class
     * @extends Developer
     */
    function UserInfoController (){
      BaseController.call(this);
        
      this.init();
    }
    
    函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。
    参数和返回值注释必须包含类型信息和说明。
    /**
     * 函数描述
     *
     * @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
        };
    }
    
    对 Object 中各项的描述, 必须使用 @param 标识。
    /**
     * 函数描述
     *
     * @param {Object} option 参数描述
     * @param {string} option.url option项描述
     * @param {string=} option.method option项描述,可选参数
     */
    function foo(option) {
        // TODO
    }
    
    重写父类方法时, 应当添加 @override 标识。如果重写的形参个数、类型、顺序和返回值类型均未发生变化,可省略 @param@return,仅用 @override 标识,否则仍应作完整注释。
    必须使用 @event 标识事件,事件参数的标识与方法描述的参数标识相同。
    /**
     * 值变更时触发
     *
     * @event
     * @param {Object} e e描述
     * @param {string} e.before before描述
     * @param {string} e.after after描述
     */
    onchange: function (e) {
    }
    
    在会广播事件的函数前使用 @fires 标识广播的事件,在广播事件代码前使用 @event 标识事件。
    常量注释

    常量必须使用 @const 标记,并包含说明和类型信息。

    /**
     * 常量说明
     *
     * @const
     * @type {string}
     */
    var REQUEST_URL = 'myurl';
    

    变量

    变量在使用前必须通过 var 定义,每个 var 只能声明一个变量。变量必须 即用即声明,不得在函数或其它形式的代码块起始位置统一声明所有变量。
    在 Equality Expression 中使用类型严格的 ===。仅当判断 null 或 undefined 时,允许使用 == null
    尽可能使用简洁的表达式。
    // 字符串为空
    
    // good
    if (!name) {
        // ......
    }
    
    // bad
    if (name === '') {
        // ......
    }
    
    // 字符串非空
    
    // good
    if (name) {
        // ......
    }
    
    // bad
    if (name !== '') {
        // ......
    }
    
    // 数组非空
    
    // good
    if (collection.length) {
        // ......
    }
    
    // bad
    if (collection.length > 0) {
        // ......
    }
    
    // 布尔不成立
    
    // good
    if (!notTrue) {
        // ......
    }
    
    // bad
    if (notTrue === false) {
        // ......
    }
    
    // null 或 undefined
    
    // good
    if (noValue == null) {
      // ......
    }
    
    // bad
    if (noValue === null || typeof noValue === 'undefined') {
      // ......
    }
    
    不要在循环体中包含函数表达式,事先将函数提取到循环体外。
    // good
    function clicker() {
        // ......
    }
    
    for (var i = 0, len = elements.length; i < len; i++) {
        var element = elements[i];
        addListener(element, 'click', clicker);
    }
    
    
    // bad
    for (var i = 0, len = elements.length; i < len; i++) {
        var element = elements[i];
        addListener(element, 'click', function () {});
    }
    
    对循环内多次使用的不变值,在循环外用变量缓存。
    类型检测优先使用 typeof。对象类型检测使用 instanceofnullundefined 的检测使用 == null
    // string
    typeof variable === 'string'
    
    // number
    typeof variable === 'number'
    
    // boolean
    typeof variable === 'boolean'
    
    // Function
    typeof variable === 'function'
    
    // Object
    typeof variable === 'object'
    
    // RegExp
    variable instanceof RegExp
    
    // Array
    variable instanceof Array
    
    // null
    variable === null
    
    // null or undefined
    variable == null
    
    // undefined
    typeof variable === 'undefined'
    

    类型转换

    转换成 string 时,使用 + ''
    转换成 number 时,通常使用 +
    string 转换成 number,要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt

    var width = '200px';
    parseInt(width, 10);
    

    转换成 boolean 时,使用 !!
    number 去除小数点,使用 Math.floor / Math.round / Math.ceil,不使用 parseInt
    使用 数组+ 拼接字符串。

    for in 遍历对象时, 使用 hasOwnProperty 过滤掉原型中的属性。
    遍历数组不使用 for in
    不会被调用的依赖模块,在文件开始处统一 require

    网络请求

    在懒加载、调用接口获取数据时,需要考虑长时间网络延迟的情况下显示加载动画。

    相关文章

      网友评论

          本文标题:js代码规范

          本文链接:https://www.haomeiwen.com/subject/qgdnzqtx.html