向更合适的API靠近

目的

在不考虑兼容以及工具的支持下,使用最新的API,以达到简洁与个人的知识更新。

ES6部分参考:
MDN官方文档
ECMAScript 6 入门

目录

  • Obect 对象操作
  • Array 数组操作
  • String 字符串操作
  • Number 数字操作
  • 其他功能整合

1,Obect 对象操作

在对象内,声明一个变量为属性名
        //bad
        var keys = 'listName';
        var obj    = {};
        obj[''+keys ] = xxx;
        
        //good
        var keys = 'listName';
        var obj    = {
               [keys]: xxx;
        };

        //在对象用内 []声明属性key,可以[]进行简单数据操作(复杂也可以,不推荐);
        var aa = 'hello';
        var bb = 'world';
        var obj1 = {
              [aa+bb]: 123;
              [bb+aa]() {              // 等同于 worldhello:function (){}
                  console.log(321);
              }
        }
        console.log(obj1.helloworld);   //  123;
        obj1.worldhello();                    //321;

Object.assign 浅复制

       //Object.assign(target, source1, source2);
      
      //bad
      var default_opt = {
            name: 'default',
            times: 10000
      }
      var params_opt = {
         name: 'name1'
      }
      for( var key in default_opt ) {
            if( typeof params_opt[key]  === 'undefind' ){   //如果直接用  if( params_opt[key] ) 会漏过 false 0 '' 等值
                params_opt[key] = default_opt[key]
            }
      }

      //good
      Object.assign(default_opt ,params_opt );   //更多用法参考文档
      //注意点,Object.assign()是浅拷贝,对于被拷贝的对象中存在嵌套对面的情况,
      //这个时候的拷贝只是引用的同一个对象,在修改复制后的对象中的嵌套对象时,
      //会引起被拷贝的对象中的嵌套对象改变,
      //个人的建议是,利用Object.assign() 这一特性,自己编写一个深度拷贝。

对象属性key遍历 Object.keys

     var obj  =  {   aaa :123,  bbb :323};
    
      //bad
      for(var key in obj) {
        console.log(obj[key])
      }

      //good
     Object.keys(obj).forEach( item => {
          console.log(obj[item]);
    })

    //更多类似的Object取属性key value用法 
    //Object.values(obj) => [123,323]
    //Object.values(obj) => [['aaa':123],['bbb',323]]

2,Array 数组操作

主要涉及到以下method
  • Array.from()
  • Array.forEach()
  • Array.reduce()
  • Array.map()
  • Array.filter()
  • Array.some()
  • Array.every()

类数组转数组 Array.from()

一般用作获取arguments、NodeList等一类的类数组转化为数组,从而进行操作。

    //老旧用法   for循环的用法更low 就不展示了
    function getInputValue() {
         var tmp_arr = [];
         [].forEach.call(document.querySelectorAll('input[name="like"]'),function (item) {
              tmp_arr.push(tmp_arr.value);
         })
        return tmp_arr.join(',');   
    }

    //替换用法
    function getInputValue() {
         var tmp_arr = [];
         Array.from(document.querySelectorAll('input[name="like"]'),forEach(function (item) {
              tmp_arr.push(tmp_arr.value);
         })
        return tmp_arr.join(',');   
     }

  //更高级的用法 reduce 可以不使用 tmp_arr 临时变量

数组循环 Array.forEach()

我觉得这个没有必要上代码,只要尽量避免在js 用 for 循环去循环一个数组

数组累加器 Array.reduce()

在 针对数组中的要进行字符串拼接,有着得天独厚的优势

    //一般的用法
    var arr  = [
             { name: '小赵'},
             { name: '小钱'},
            { name: '小孙'},
             { name: '小李'}  
          ];

    //一般的用法
    function getNames() {

            var tmp_str = '';

            arr.forEach( item => {
                tmp_str += item.name + ' ';
            });

            return tmp_str;
      }

    //更好用法
    function getNames() {

          return arr.reduce((total,item) => {

              return `${total} ${item.name}`

            },'');
      }

然而 `` 跟 ${} 又是什么 ,那就等看一下 String 的扩展了

基于一个数组生成新数组 Array.map()

基于一个数组,可以循环该数组的每个成员并返回拿到成员值做特殊处理的结果,重新组成新数组

    var arr = [9,8,10,11,12];
    //bad 
    var new_arr = [];
    arr.forEach( item => {
      new_arr.push( item * 10 );
    })

    //good
    var new_arr;
    new_arr = arr.map( item => {
      return item * 10
    })
    //这个也没什么必要讲

数组过滤器 Array.filter()

过滤一个数组,对一个数据进行数据筛选,并返回一个通过的筛选值组成的新数组

    var arr = [9,8,10,11,12];
    //bad 
    var new_arr = [];
    arr.forEach( item => {
          if( item >= 10){
              new_arr.push( item * 10 );
          }
    })

    //good
    var new_arr;
    new_arr = arr.filter( item => {
      return item >= 10;
    })

数组循环判断 Array.some()

这个用得比较多,作用就是去 替换 数组for循环中存在终止条件break

  var arr = [
                {id:1,isSelected:false},
                {id:2,isSelected:true},
                {id:3,isSelected:false}
            ];
  
    var flag_has_select = false;

    //bad A
    var i;
    var len;
    for( i = 0,len = arr.length; i < len; i++) {
        if( arr[i].isSelected ) {
            flag_has_select = true;
            break;
        }
    }

    //bad B
    arr.forEach( item => {
        if( item.isSelected ){
            flag_has_select = true;
            //forEach 无法中断
        }
    })

    //good
    flag_has_select = arr.some( item => {
        return item.isSelected;
        //if( item.isSelected ) { return true}
    })

数组循环判断 Array.every()

    var arr = [
                {id:1,isSelected:false},
                {id:2,isSelected:true},
                {id:3,isSelected:false}
            ];
    
    var flag_all_select = true;

    //bad 
    arr.forEach( item => {
        if( !item.isSelected ){
            flag_all_select = false;
        }
    })

    //good
    flag_all_select = arr.every( item => {
        return item.isSelected;
    })

3,String 字符串操作

最明确的一点 不再出现 html += 'xxx' + xxx + 'xxx' 这类的操作,该用模板引擎的用模板引擎,该 字符串 拼接的 采用 `反引号${ 变量 }拼接。

模板字面量

   //bad A
  html = '/api/user/' + useId;
  //good A
  html = `api/user/${userId}`;

  //bad B
  data.forEach( item => {
    html += '<li>' + item.name + '</li>';
  })
  //good B
  data.forEach( item => {

    //在能够确认数据不会包含 xss 攻击 且 dom 字符拼接较少时
    html += `<li>${item.name}</li>`;
    
    //当数据存在包含 xss 攻击的可能性 或者 大量的 dom 字符拼接
    html += template(item);

    //xss 攻击中的一种主要是用户通过输入信息包含 <script> 脚本语言 对用户信息的盗用
   //最简单的就是 将用户的输入的数据 用正则将 ‘<’ ‘>’ 转化成 &gt &lt
  })
  

4,Number 数值操作

最明确的一点 一切数值、字符串判断 用 === 强等进行

虽然JavaScript是弱类型语言,但是对自己的代码要以强类型的去对待。虽然有些判断 == 也没有问题,但是要养成良好的数据类型预定与判断(flow js数据类型检验工具)

Number()

    var input_val = document.getElementById('input').value;
    //bad A
    if( input_val == 2 ) {}
    //good A
    if( Number(input_val ) === 2) {}
    
    var show_text_span = document.getElementById('count_span');
    //bad B
    show_text_span.innerText = 1 + input_val ;
    //good B
    // 避免 1 + ‘0’ = ‘10’ 的情况出现;
    // 当然一般不是这么写, input_val还要用过 isNaN之类的判断,这里假设input_val是 数值型的字符串
     show_text_span.innerText = 1 + Number(input_val) ;

5,其他功能整合

1. 不要过度的使用 if else / if esle if else 嵌套

太多的if else嵌套给阅读代码的人容易造成一种难以快速理解的感觉

    //bad
    function getSelectInfo(obj){
        var text = ''
        if( obj.isSelected ) {
           text  = '已选中';
        } esle {
          text  = ‘未选中’;
        }
        return text;
    }

    //better
    function getSelectInfo(obj){
        var text = '未选中'
        if( obj.isSelected ) {
           text  = '已选中';
        }
        return text;
    }

有时候,换一个策略,可能使得代码更简洁。

    var data = { key: 'sending' || 'sended' || 'ok' || 'error'}  //后面的可能会出现其中一个

    //bad   这代码我看着难受
    function getSendStatus(dataObj){
        var text = ''
        if( dataObj.key === 'sending' ) {
           text  = '发送中';
        } esle if( dataObj.key === 'sended') {
          text  = ‘已发送’;
        } else if( dataObj.key === 'ok' ) {
           text  = ‘发送成功’;
        } else if( dataObj.key === 'error' ) {
          text  = ‘发送出错’;
        }
        return text;
    }
    // 小知识点,js 中 只有 if else 没有 if else if else? 真的吗?查查
    //虽然可以采用 switch 做一下优化,但是条件多总给人一种需要花费时间去理解的感觉 

    //better
    var status_obj = {   
        'sending': '发送中',
        'sended': '已发送',
        'ok': '发送成功',
        'error': '发送出错'
    };
     // 如果status_obj 是一次性的 那么可以放在getSelectInfo内部,
     // 如果多次使用 考虑与getSelectInfo 采用 单例模式 ,避免暴露更多的无用变量到上层作用域;

    function getSelectInfo(dataObj){
        return status_obj[dataObj.key];
    }

    // 当然 上面的代码是肯定已经肯定 data.key只有4个值,
    // 在实际生产当中总是需要考虑一个默认值用于超出预期处理
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容