美文网首页
Javascript团队规范(总)

Javascript团队规范(总)

作者: 天外来人 | 来源:发表于2016-05-31 19:28 被阅读35次

    Arrays

    1 给数组添加项时,使用push 而不用 arr[arr.length] = ''"

    var arr = [];
    
    //bad
    arr[arr.length] = '123321';
    
    //good
    arr.push('123321');
    

    2 复制数组时候:使用slice

    var len = items.length;
    var itemsCopy = [];
    var i;
    
    //bad
    for(i = 0; i < len; i++){
      itemsCopy[i] = item[i];
    }
    
    //good
    itemsCopy = items.slice();
    

    3 将一个类数组转成数组时候:使用slice

    var args = Array.prototype.slice.call(arr);
    

    Functions

    1 不要在非函数代码块(if while 等)中声明函数, 把那个函数赋给一个变量。浏览器允许你这么做,但它们的解析表现不一致。

    // bad
    if (currentUser) { 
      function test() { 
        console.log('Nope.'); 
      }
    }
    // good
    var test;
    if (currentUser) { 
      test = function test() {
        console.log('Yup.'); 
      };
    }
    

    2 永远不要把参数命名为 arguments. 这将取代函数作用域内的arguments对象。

    Properties

    1 使用.来访问对象的属性

    var luke = {
      jedi: true,
      age: 28
    };
    
    //bad
    var isJedi = luke['jedi'];
    
    //good
    var isJedi = luke.jedi;
    

    2 当通过变量访问属性时使用中括号[]。

    var luke = {
      jedi: true, 
      age: 28
    };
    function getProp(prop) { 
      return luke[prop];
    }
    var isJedi = getProp('jedi');
    

    变量

    1 总是使用var 来声明变量。避免产生全局变量,避免污染全局命名空间。
    2 每个var 只能声明一个变量。原因:如果var 声明多给变量,容易导致较长的行长度,并且在修改时容易造成逗号和分号的混淆.
    3 在作用域的顶部声明变量,这样做,可以避免因变量提升而带来的问题。

    //bad
    function () {
      test();
      console.log("doing stuff...");
      //..other stuff..
      if(name === 'test') {
        return false;
      }
      return name;
    }
    //good
    function () {
      var name = getName();
      test();
      console.log('dong stuff..');
      //..other stuff..
      if(name === 'test'){
        return false;
      }
      return name;
    }
    

    4 最后声明未赋值的变量。当你需要引用前面的变量赋值时这将变得很有作用。

    //bad
    var i;
    var items = getItems();
    var dragonball;
    var goSportsTeam = true;
    var len;
    
    //good
    var items = getItems();
    var dragonball;
    var goSportsTeam  = true;
    var len;
    

    变量提升

    1 变量声明会提升至作用域顶部,但赋值不会。
    2 匿名函数表达式会提升它们的变量名,但不会提升函数的赋值
    3 命名函数表达式会提升变量名,但不会提升函数名或函数体
    4 函数声明提升它们的名字和函数体

    function example() { 
      console.log(named); // => undefined 
      named(); // => TypeError named is not a function 
      superPower(); // => ReferenceError superPower is not defined   
      
     var named = function superPower() { 
        console.log('Flying'); 
      };}
    
    function example() { 
       console.log(named); // => undefined 
       named(); // => TypeError named is not a function 
       var named = function named() { 
        console.log('named'); 
      }
    }
    

    条件

    1 优先使用 === 和 !== 而不是 == 和 !=
    2 尽可能使用简洁的表达式。

    //字符串为空
    // 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'){
    }
    

    3 按执行频率排列分支的顺序。原因:提高执行效率和检查代码的出错效率。

    命名

    1 变量,函数名、函数的参数,类的属性、方法,命名空间使用Camel(骆驼)命名法。

    var loadingModules = {}; //变量
    function stringFormat(theBells) {}; //函数名,参数
    function Person(name, age){  //类的属性,方法
      this.name = name;
      this.age = age;
    }
    Person.prototype.getName = function() {};
    equipments.heavyWeapons = {}; //命名空间
    

    2 类名,枚举变量名使用Pascal(帕斯卡)命名法。

    function TextNode() {} //类名
    var TargetState = {}; //枚举变量
    

    3 常量,枚举变量的属性 使用 全部字母大写,单词间以下划线分隔 的命名方式。

    var HTML_ENTITY = {}; //常量
    var TargetState = { //枚举变量属性
      READING: 1,
      READED: 2,
      READY: 3
    };
    

    4 以下划线"_"开头命名私有变量

    //bad
    this._firstName_ = "123";
    this.firstName = '123';
    
    //good
    this._firstName = '123';
    

    5 当要保存this时候,使用_this来保存

    //bad
    function () {
      var self = this;
      return function () {
        console.log(self);
      }
    }
    //good
    function () {
      var _this = this;
      return function () {
        console.log(_this);
      }
    }
    

    6 类名使用 名词,函数名使用 动宾短语, Promise对象(遗留问题) 用动宾短语的进行时。

    function Engine(options) {} //类名
    function getStyle(){ //函数名
    } 
    var loadingData = ajax.get('url'); //Promise对象
    loadingData.then(callback);
    

    7 boolean 类型的变量使用 is 或 has 开头。

    var isReady = false;
    var hasMoreCommands = false;
    

    8 给函数命名。这在做堆栈轨迹时很有帮助

    //bad
    var log = function (msg) {
      console.log(msg);
    };
    //good
    var log = function log(msg) {
      console.log(msg);
    }
    

    9 如果你的文件导出一个类,你的文件名应该与类名完全相同

    class checkBox {
      //..
    }
    module.exports = checkBox;
    //in some other file
    //bad
    var CheckBox = require('./checkBox');
    //bad
    var CheckBox = require('./check_box');
    //good
    var CheckBox = require('./CheckBox');
    

    空格

    此部分只需要了解,因为sublineText3的格式化代码插件已经帮助开发人员做到了
    1 二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格。

    a = b + c;
    var a = !true;
    

    2 用作代码块起始的左花括号"{"前必须有一个空格。

    //bad
    function show (){
    }
    //good
    function show () {
    }
    

    3 if / else / for / while / function...关键字后,必须有一个空格。

    if (condition) {
    }
    

    4 对象中,属性中":"之后必须有空格,":"之前不允许有空格。

      var obj = {
        a: 1,
        b: 2
      };
    

    5 "," 和";"前不允许有空格。

    //bad
    callFunc(a , b);
    
    //good
    callFunc(a, b); 
    

    6 在函数调用、函数声明、括号表达式、属性访问、if/for 等语句中,()和 [] 内紧贴括号部分不允许有空格。

    //  bad
    callFunc( param1, param2, param3 );
    if( num > list.length ){
    }
    while( len-- ){
    }
    
    //  good
    callFunc(param1, param2, param3);
    if(num > list.length)}{
    }
    while(len--) {
    }
    

    换行问题

    1 单行声明的数组与对象,如果包含元素,{}和[]内紧贴括号部分不允许包含空格。另外当内部元素的形式较为复杂时候,还应该换行书写。

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

    2 运算符处换行时,运算符必须在新行的行首。(并未强调换行时,运算符必须在行首)

    if (user.isAuthenticated() 
        && user.isInRole('admin') 
        && user.hasAuthority('add-admin') 
        || user.hasAuthority('delete-admin')
    ) {
        // Code
    }
    var result = number1 + number2 + number3 
                       + number4 + number5;
    

    3 在语句的行长度超过 120 时, 根据逻辑条件合理缩进。(额外)

    // 按一定长度截断字符串,并使用 + 运算符进行连接。
    // 分隔字符串尽量按语义进行,如不要在一个完整的名词中间断开。
    // 特别的,对于HTML片段的拼接,通过缩进,保持和HTML相同的结构。
    var html = '' // 此处用一个空字符串,以便整个HTML片段都在新行严格对齐 
        + '<article>' 
        + '<h1>Title here</h1>' 
        + '<p>This is a paragraph</p>' 
        + '<footer>Complete</footer>' 
        + '</article>';
    // 也可使用数组来进行拼接,相对 + 更容易调整缩进。
    var html = [ 
        '<article>', 
          '<h1>Title here</h1>', 
          '<p>This is a paragraph</p>',    
        '</article>'];
    html = html.join('');
    
    // 当参数过多时,将每个参数独立写在一行上,并将结束的右括号 ) 独立一行。
    // 所有参数必须增加一个缩进。
    foo(
      aVeryVeryLongArgument, 
      anotherVeryLongArgument, 
      callback
    );
    
    // 链式调用较长时采用缩进进行调整。
    $('#items') 
        .find('.selected')
        .highlight() 
        .end();
    
    // 也可以按逻辑对参数进行组合。
    // 最经典的是baidu.format函数,调用时将参数分为“模板”和“数据”两块
    baidu.format( 
      dateFormatTemplate, 
      year, month, date, hour, minute, second
    );
    

    4 当在程序中生成一个字符串时候,使用Array 而不是用 "+"拼接

    var items;
    var messages;
    var length;
    var i;
    messages = [{ 
      state: 'success',
      message: 'This one worked.'
    }, { 
      state: 'success', 
      message: 'This one worked as well.'
    }, { 
      state: 'error', 
      message: 'This one did not work.'
    }];
    length = messages.length;
    
    // bad
    function inbox(messages) { 
      items = '<ul>'; 
      for (i = 0; i < length; i++) { 
        items += '<li>' + messages[i].message + '</li>'; 
      } 
      return items + '</ul>';
    }
    // good
    function inbox(messages) { 
       items = []; 
       for (i = 0; i < length; i++) { 
       // use direct assignment in this case because we're micro-optimizing. 
         items[i] = '<li>' + messages[i].message + '</li>'; 
      } 
      return '<ul>' + items.join('') + '</ul>';
    }
    

    类型转换

    在语句开始时执行类型转换
    1 转字符串

    //bad
    var str = str2 + '';
    //good
    var str = '' + str2;
    
    //bad
    var str = '' + str2 + '123';
    //good
    var str = '123' + str2;
    

    2 转Number,转换数字时总是带上类型转换基数

    var num = '4';
    
    //bad
    var val = parseInt(num);
    
    //good
    var val = Number(num);
    var val = parseInt(inputValue, 10);
    

    3 转Booleans

    var age = 0;
    
    //bad
    var hasAge = new Boolean(age);
    
    //good
    var hasAge = Boolean(age);
    var hasAge = !!age
    

    构造函数

    给对象原型分配方法,而不是使用一个新对象覆盖原型。覆盖原型将导致继承出现问题:重设原型将覆盖原有原型!

    function Jedi() { 
      console.log('new jedi');
    }
    
    // bad
    Jedi.prototype = { 
      fight: function fight() { 
        console.log('fighting');
      }, 
      block: function block() { 
        console.log('blocking'); 
      }
    };
    
    // good
    Jedi.prototype.fight = function fight() {   
      console.log('fighting');
    };
    Jedi.prototype.block = function block() { 
      console.log('blocking');
    };
    

    2 为了能实现链式调用,可以在每个方法中返回return this

    // bad
    Jedi.prototype.jump = function jump() { 
      this.jumping = true; 
      return true;
    };
    
    Jedi.prototype.setHeight = function setHeight(height) { 
      this.height = height;
    };
    
    var luke = new Jedi();
    luke.jump(); // => true
    luke.setHeight(20); // => undefined
    
    // good
    Jedi.prototype.jump = function jump() { 
      this.jumping = true; 
      return this;
    };
    Jedi.prototype.setHeight = function setHeight(height) { 
      this.height = height; 
      return this;
    };
    var luke = new Jedi();
    luke.jump() 
          .setHeight(20);
    

    事件

    在注册事件(on)以及触发注册事件(trigger)中,参数要以json的格式传递。这是为了以后修改过程中,不需要更新trigger函数。

    //bad
    $(this).trigger('listingUpdated', listing.id);
    ...
    $(this).on('listingUpdated', function (e, listingId) { 
      // do something with listingId
    });
    
    //good
    $(this).trigger('listingUpdated', { listingId : listing.id });
    ...
    $(this).on('listingUpdated', function (e, data) { 
      // do something with data.listingId
    });
    

    JQuery

    1 jQuery对象以$开发命名

    // bad
    var sidebar = $('.sidebar');
    // good
    var $sidebar = $('.sidebar');
    

    2 当多次使用jQuery对象的时候,缓存jQuery对象

    // bad
    function setSidebar() { 
      $('.sidebar').hide(); 
      // ...stuff... 
      $('.sidebar').css({ 'background-color': 'pink' });}
      
     // good
     function setSidebar() { 
       var $sidebar = $('.sidebar'); 
       $sidebar.hide(); 
       // ...stuff... 
       $sidebar.css({ 
        'background-color': 'pink' 
       });
    }
    

    3 查找jQuery对象的时候,如果存在层级(父子)关系的时候,使用$('.sidebar ul') 或 $('.sidebar > ul')

    //bad
    $('ul', '.sidebar').hide();
    $('.sidebar').find('ul').hide();
    
    //good
    $('.sidebar ul').hide();
    $('.sidebar > ul').hide();
    $sidebar.find('ul').hide();
    

    4 对有作用域的jQuery对象查询使用find

    参考文献
    https://github.com/airbnb/javascript/tree/master/es5#naming-conventions
    https://github.com/sivan/javascript-style-guide/blob/master/es5/README.md#variables

    相关文章

      网友评论

          本文标题:Javascript团队规范(总)

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