美文网首页
javascript语言编码规范

javascript语言编码规范

作者: 北疆小兵 | 来源:发表于2019-11-19 18:34 被阅读0次

    javascript语言编码规范

    命名

    • [强制] 变量 使用 Camel命名法。
    var loadingModules = {};
    
    • [强制] 常量 使用 全部字母大写,单词间下划线分隔 的命名方式
    var HTML_ENTITY = {};
    
    • [强制] 函数 使用 Camel命名法,可使用常见动词约定
      • can 判断是否可执行某个动作,函数返回一个布尔值。true:可执行;false:不可执行
      • has 判断是否含有某个值, 函数返回一个布尔值。- true:含有此值;false:不含有此值
      • is: 判断是否为某个值,函数返回一个布尔值。true:为某个值;false:不为某个值
      • get: 获取某个之,函数返回一个非布尔值
      • set: 设置某个值,无返回值、返回是否设置成功或者返回链式对象 load 加载某些数据,无返回值或者返回是否加载完成的结果
    • [强制] 函数的 参数 使用 Camel命名法。
    function hear(theBells) {
    }
    
    • [强制] 类 使用 Pascal命名法
    function TextNode(options) {
    }
    
    • [强制] 枚举变量 使用 Pascal命名法,枚举的属性 使用 全部字母大写,单词间下划线分隔 的命名方式。

      var TargetState = {
          READING: 1,
          READED: 2,
          APPLIED: 3,
          READY: 4
      };
      
    • [强制] 由多个单词组成的缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致

      function XMLParser() {
      }
      
      function insertHTML(element, html) {
      }
      
      var httpRequest = new HTTPRequest();
      
      
    • [强制] 类名 使用 名词

      function Engine(options) {
      }
      
    • [建议] boolean 类型的变量使用 is 或 has 开头。

      var isReady = false;
      var hasMoreCommands = false;
      

    代码风格

    • 导出的默认函数使用驼峰命名、文件名与函数完全一致。
    • 导出单例、函数库、空对象时使用帕斯卡式命名(帕斯卡式命名法是在命名的时候将首字母大写, 如: DisplayInfo
    • if / else / for / while / function / switch / do / try / catch / finally 关键字后,必须有一个空格
    // good
    if (condition) {
    }
    
    while (condition) {
    }
    
    (function () {
    })();
    
    // bad
    if(condition) {
    }
    
    while(condition) {
    }
    
    (function() {
    })();
    
    
    • 在对象创建时,属性中的 : 之后必须有空格,: 之前不允许有空格
      示例:
    
    // good
    var obj = {
        a: 1,
        b: 2,
        c: 3
    };
    
    // bad
    var obj = {
        a : 1,
        b:2,
        c :3
    };
    
    
    • 函数声明、具名函数表达式、函数调用中,函数名和 ( 之间不允许有空格。
    // good
    function funcName() {
    }
    
    var funcName = function funcName() {
    };
    
    funcName();
    
    // bad
    function funcName () {
    }
    
    var funcName = function funcName () {
    };
    
    funcName ();
    
    
    • 逗号写在行尾, 并且增加结尾的逗号。
    • 使用分号, 以分号作为语句的结束符
    
    # good
    const obj = {
      firstName: 'Dana',
      lastName: Scally',
    };
    
    
    # bad
    const obj = {
      firstName: 'Dana',
      lastName: 'Scally'
    };
    
    
    • 使用大括号包裹所有的多行代码块
    • 如果通过if和else使用多行代码块, 把else放在if代码块关闭括号的同一行。
    if(arg) {
      return arg;
    } else {
      return false;
    }
    
    • 不要使用通配符 *的import
    • 如果你的文件只输出一个类, 那你的文件名必须和类名完全保持一致。
    import CheckBox from './CheckBox';
    

    类型和变量

    • 变量必须显式声明作用域
      • var => 用于声明全局变量或函数级变量
      • let => 用于声明块级的局部变量
      • const => 声明块级域的只读局部变量
    • 尽量对所有的引用使用const, 不要使用var。 如果你一定需要使用可变动的引用,使用let代替var
    • 将所有的const和let分组
    • 在需要的地方给变量赋值
    // good
    const a = 1;
    const b = 2;
    
    let count = 1;
    if (true) {
        count += 1;
    }
    
    
    // bad
    var a = 1;
    var b = 2;
    
    var count = 1;
    if (true) {
        count += 1;
    }
    
           
    
    • [强制] 每个 var 只能声明一个变量。

    一个 var 声明多个变量,容易导致较长的行长度,并且在修改时容易造成逗号和分号的混淆

    // good
    var hangModules = [];
    var missModules = [];
    var visited = {};
    
    // bad
    var hangModules = [],
    missModules = [],
    visited = {};
    
    
    • 变量必须 即用即声明,不得在函数或其它形式的代码块起始位置统一声明所有变量。

    变量声明与使用的距离越远,出现的跨度越大,代码的阅读与维护成本越高。虽然JavaScript的变量是函数作用域,还是应该根据编程中的意图,缩小变量出现的距离空间。

    条件

    • 在 Equality Expression 中使用类型严格的 ===。仅当判断 null 或 undefined 时,允许使用 == null。

    使用 === 可以避免等于判断中隐式的类型转换。

    // good
    if (age === 30) {
        // ......
    }
    
    // bad
    if (age == 30) {
        // ......
    }
    
    
    • 尽可能使用简洁的表达式。
    // 字符串为空
    
    // 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') {
      // ......
    }
    
    
    
    • [建议] 对于相同变量或表达式的多值条件,用 switch 代替 if。
    
    // good
    switch (typeof variable) {
        case 'object':
            // ......
            break;
        case 'number':
        case 'boolean':
        case 'string':
            // ......
            break;
    }
    
    // bad
    var type = typeof variable;
    if (type === 'object') {
        // ......
    }
    else if (type === 'number' || type === 'boolean' || type === 'string') {
        // ......
    }
    
    
    • [建议] 如果函数或全局中的 else 块后没有任何语句,可以删除 else。
    / good
    function getName() {
        if (name) {
            return name;
        }
    
        return 'unnamed';
    }
    
    // bad
    function getName() {
        if (name) {
            return name;
        }
        else {
            return 'unnamed';
        }
    }
    
    

    循环

    • [建议] 不要在循环体中包含函数表达式,事先将函数提取到循环体外。

    循环体中的函数表达式,运行过程中会生成循环次数个函数对象

    // 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 () {});
    }
    
    
    • [建议] 对循环内多次使用的不变值,在循环外用变量缓存
    // good
    var width = wrap.offsetWidth + 'px';
    for (var i = 0, len = elements.length; i < len; i++) {
        var element = elements[i];
        element.style.width = width;
        // ......
    }
    
    
    // bad
    for (var i = 0, len = elements.length; i < len; i++) {
        var element = elements[i];
        element.style.width = wrap.offsetWidth + 'px';
        // ......
    }
    
    
    • [建议] 对有序集合进行遍历时,缓存 length。

    虽然现代浏览器都对数组长度进行了缓存,但对于一些宿主对象和老旧浏览器的数组对象,在每次 length 访问时会动态计算元素个数,此时缓存 length 能有效提高程序性能。

    for (var i = 0, len = elements.length; i < len; i++) {
        var element = elements[i];
        // ......
    }
    
    
    • [建议] 对有序集合进行顺序无关的遍历时,使用逆序遍历。

    逆序遍历可以节省变量,代码比较优化。

    var len = elements.length;
    while (len--) {
        var element = elements[len];
        // ......
    }
    
    

    类型

    类型检测

    • [建议] 类型检测优先使用 typeof。对象类型检测使用 instanceof。null 或 undefined 的检测使用 == 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 时,使用 + ''。
    
    // good
    num + '';
    
    // bad
    new String(num);
    num.toString();
    String(num);
    
    
    • [建议] 转换成 number 时,通常使用 +。
    • string 转换成 number,要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt。
    let width = '200px';
    parseInt(width, 10);
    
    
    • [强制] 使用 parseInt 时,必须指定进制。
    // good
    parseInt(str, 10);
    
    // bad
    parseInt(str);
    
    
    • [建议] 转换成 boolean 时,使用 !!。
    let num = 3.14;
    !!num;
    
    • [建议] number 去除小数点,使用 Math.floor / Math.round / Math.ceil,不使用 parseInt。
    // good
    let num = 3.14;
    Math.ceil(num);
    
    // bad
    let num = 3.14;
    parseInt(num, 10);
    
    
    

    对象和引用

    • [强制] 使用对象字面量 {} 创建新 Object。
    // good
    var obj = {};
    
    // bad
    var obj = new Object();
    
    • [建议] 对象创建时,如果一个对象的所有 属性 均可以不添加引号,建议所有 属性 不添加引号。
    var info = {
        name: 'someone',
        age: 28
    };
    
    
    • [建议] 对象创建时,如果任何一个 属性 需要添加引号,则所有 属性 建议添加 '。

    如果属性不符合 Identifier 和 NumberLiteral 的形式,就需要以 StringLiteral 的形式提供。

    # good
    var info = {
       'name': 'someone',
       'age': 28,
       'more-info': '...'
    };
    # bad
    var info = {
       name: 'someone',
       age: 28,
       'more-info': '...'
    };
    
    
    • 属性访问时,尽量使用 .。

    通常在 JavaScript 中声明的对象,属性命名是使用 Camel 命名法,用 . 来访问更清晰简洁。部分特殊的属性(比如来自后端的 JSON ),可能采用不寻常的命名方式,可以通过 [expr] 方式访问。

    info.age;
    info['more-info'];
    
    
    • 使用对象方法的简写
    # good
    let name = "zhangsan"
    const obj = {
        name
    }
    
    
    # bad
    let name = "zhangsan"
    const obj = {
        name:name
    }
           
    
    • 访问外部对象时, 需要先判断对象是否为空

    String

    • [强制] 字符串开头和结束使用单引号 '。

    1.输入单引号不需要按住 shift,方便输入。
    2.实际使用中,字符串经常用来拼接 HTML。为方便 HTML 中包含双引号而不需要转义写法。

    var str = '我是一个字符串';
    var html = '<div class="cls">拼接HTML可以省去双引号转义</div>';
    
    
    • 长度超过80的字符串应该使用字符串连接换行。
    • 构建字符串时, 使用字符串模板而不是字符串连接。
    function sayHi(name) {
      return `How are you, ${name}`;
    }
    
    

    数组

    • [强制] 使用数组字面量 [] 创建新数组,除非想要创建的是指定长度的数组。
    // good
    var arr = [];
    
    // bad
    var arr = new Array();
    
    
    • [强制] 遍历数组不使用 for in。

    数组对象可能存在数字以外的属性, 这种情况下 for in 不会得到正确结果。

    • [建议] 不因为性能的原因自己实现数组排序功能,尽量使用数组的 sort 方法。

      自己实现的常规排序算法,在性能上并不优于数组默认的 sort 方法。以下两种场景可以自己实现排序:需要稳定的排序算法,达到严格一致的排序结果。
      数据特点鲜明,适合使用桶排。

    • [建议] 清空数组使用 .length = 0。

    • 使用扩展运算符 ... 复制数组

      扩展运算符可以减少赋值语句的使用, 或者减少通过下标访问数组或对象的方式, 使用代码更加简洁优雅, 可读性更佳

    ```
    # good
    const itemsCopy = [...items];
    
    # bad
    const len = items.length;
    const itemsCopy = [];
    
    let i;
    for(i=0; i<len; i++) {
      itemsCopy[i] = items[i];
    }
    
    ```
    

    函数

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

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

    • 通过 options 参数传递非数据输入型参数。

    有些函数的参数并不是作为算法的输入,而是对算法的某些分支条件判断之用,此类参数建议通过一个 options 参数传递。

    #good
    /**
     * 移除某个元素
     *
     * @param {Node} element 需要移除的元素
     * @param {Object} options 相关的逻辑配置
     * @param {boolean} options.removeEventListeners 是否同时将所有注册在元素上的事件移除
     */
    function removeElement(element, options) {
        element.parent.removeChild(element);
    
        if (options.removeEventListeners) {
            element.clearEventListeners();
        }
    }
    
    # bad
    /**
     * 移除某个元素
     *
     * @param {Node} element 需要移除的元素
     * @param {boolean} removeEventListeners 是否同时将所有注册在元素上的事件移除
     */
    function removeElement(element, removeEventListeners) {
        element.parent.removeChild(element);
    
        if (removeEventListeners) {
            element.clearEventListeners();
        }
    }
    
    • [建议] 空函数不使用 new Function() 的形式。
    var emptyFunction = function () {};
    

    箭头函数

    • 别保存this的引用, 使用箭头函数或Function.bind
    • 当你必须使用函数表达式(或传递一个匿名函数)时, 使用箭头函数
    # good
        [1, 2, 3].map( (x) => {
            return x * x;
        });
        
        # bad
        [1, 2, 3].map(function(x) {
          return x * x;
        });
    
    
    
    • 如果一个函数适用一行写出并且只有一个参数, 那就把花括号、圆括号和return都省略掉, 如果不是, 那就不要省略。
    ```
    [1, 2, 3].map( x => x * x;);
    ```
    

    解构

    • 使用解构存取和使用多属性对象。

    说明:
    ES6允许按照一定的模式, 从数组和对象中提取值、对变量进行赋值, 这称之为解构, 解构赋值避免了临时变量或对象, 给JavaScript书写带来了很大的便利性, 同时也提高了代码的可读性。

    # good
    
    let user = {
        firstName: "Jack",
        lastName: "Ma",
    };
    
    function getFullName({firstName,lastName}){
        return `${user.firstName} ${user.lastName}`;
    }
    # bad
    function getFullName (user) {
      const firstName = user.firstName;
      const lastName = user.lastName;
      return  `${firstName} ${lastName}`;
    }
    
    • 需要回传多个值时, 使用对象解构, 而不是数组解构

    对象解构在增加属性或改变排序时, 无需改变调用时的位置。

    相关文章

      网友评论

          本文标题:javascript语言编码规范

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