美文网首页
ECMAScript 5 常用的技巧(一)

ECMAScript 5 常用的技巧(一)

作者: BGING | 来源:发表于2018-01-05 11:20 被阅读0次

    结合自己编码遇到的小坑的积累吧。因此下面会有一些个人的见解,参考书籍《JavaScript高级程序设计》(第三版)

    尽量不适用 var 声明局部变量

    在 esc5 中 var 声明变量是一个万能的方式,往往因为太便利了就会出现一些问题。例如我其实只是想让一个变量在局部作用域中有效果,但是在下面的代码却出现了问题。

    // 猜猜下面执行后的结果。
    
    var a = { a: 2 }
    var b = { a: 2 }
    if (a) {
        a.a = 1;
        var a = new Object();
        a.a = 3;
    
    }
    
    // 如果你讲 if 里的 var 换成 let 会抛出异常,需要将 a.a=1 注销掉才可以。
    console.error(a); // 3
    
    function str(b) {
        b.a = 1;
        var b = new Object();
        b.a = 3;
    }
    str(b)
    console.log(b); // 1
    
    for (var i = 0; i < 3; i++) {
        var b = 2
    }
    console.log(i); // 3
    console.log(b); // 2
    
    

    所以在声明变量的时候最好是用 let 而不是 var 这也是 ECMAScript6 推荐的做法。

    Array 数组

    其实数组里还是设计到数据结构栈类似的存储结构,对栈的认识 可以参考这个链接

    • array.length :不仅可读,还是可以通过设置长度截取或增加数组的内容。并且会更爱原数组;当然新增数组的内容默认值是 undefined

    • 判断数组

      • 针对一个网页,或者是一个框架环境的情况下,用 instanceof 就可以实现。

        if( value instanceof Array){
          //对数组执行操作
        }
        
        
      • 网页中如果包含多个框架,一个框架的 Array 值传递进入另一个框架做是否数组的判断。用Array.isArray()

        if(Array.isArray( value )){
          // 对数组执行的操作
        }
        
    • 数组排序 sortreserve

      // sort 的排序方式是比较函数通过返回值小于零、大于零、等于零来影响排序结果,减法的操作就可以适用部分情况。
      
      var arr = [2,3,1,3,4,5,1];
      
      var sortArray = arr.sort(
                function (a, b){
                      return b - a;
                    //return a < b ? 1 : -1; 
                      
                }
             );
             // 倒叙排列
             console.error(sortArray);
      
      // 正序排列
      function compare(value1, value2){
                if(value1 < value2){
                    return -1;
                }else if( value1 > value2){
                    return 1;
                }else{
                    return 0;
                }
                
       }
        //var sortArray =arr.sort(compare);
      
             // reserve 的作用就是反转已经排好的顺序。
      
        var reverseSort = sortArray.reverse();
            
        console.log(reverseSort);
      
    • 数组合并 concat

        var color = ['green']; // color 的值不变
      
        var colors = color.concat('yellow', ['blue','red']);
      
      
    • 数组截取 slice

      
      
      // 不会影响原数组
      var colors = ["green", "yellow", "blue", "red"];
      
      colors.slice(1); // ["yellow", "blue", "red"];
      
      // 返回起始位置的值,单不包含结束位置的值;
      colors.slice(1,3); //["yellow", "blue"]
      
    • 数组splice 删除、新增、修改操作

      
      var arr = [1,2,3,4];
      // 删除
      //arr.splice(起始下标, 删除项数)
      arr.splice(0,1);  // 返回删除的项1, 
      arr = [2,3,4];
      
      //替换 or 新增
      //arr.splice(起始下标, 删除项目,替换的值)
      
      arr.splice(0, 0 ,4); // arr = [4, 1, 2, 3, 4]
      
      arr.splice(0, 1, 5); // arr = [5, 2, 3, 4]
      
      
    • 位置方法 indexOf、lastIndexOf

      // 可以接受2个参数, 下标是可选的,如果字符有,下标正确,返回下标值,否则返回 -1
      
      str.indexOf(字符, 下标);
      // 我们一般的书写代码习惯
      let a = "foo";
      if(a.indexOf('a') != -1){
        //...
      }
       // 其实这个代码可以简化下
      if(~a.indexOf(a)){
        // 这样就简化了代码
      }
      这里就必须补充一个知识点了
      ~42 ===> -(42+1) = -43
      所以 ~-1 = 0
      
      
    • 迭代数组,执行一个方法,查看返回值 every、filter、forEach、map、some

    • 迭代数组的每一项 reduce、reduceRight

      var arr = [1,2,3];
      arr.reduce(function(prev, curr, index, array){
        return prev + curr;
      })
      
      // 6
      
      reduce & reduceRight 功能都一致,只是顺序不同。
      

    正则

    RegExp 每次执行都会创建一个新的构造函数,并且只接收字符串

    // exec 返回匹配的第一个值
    
    // test
    
    
    

    函数

    • 内部属性 arguments、this、callee

      // 解除递归 函数和函数名的耦合
      function str(num){
        if(num <= 1){
          return 1;
        }else{
          return num + arguments.callee(num -1);
        }
      }
      str(7); //28
      
      
    • apply、call

    // 1、apply、和call 相同点:都是指定方法在被调用的作用域
    //                 不同点:apply,第二个参数是,方法接收参数用数组传递;call 是直接一个一个书写。
    
    function a(num1, num2){
        return num1 + num2;
    }
     function b(num1, num2){
       //return a.apply(this, arguments);
        return a.call(this, num1, num2);
     }
      b(1,2); //3
    
    
    // 方法内部继承,实例化方法调用。
      function animal(name){
        this.name= name || "animal";
        this.getName = function(name){
          return this.name;
        }
      }
    
      function dog(name){
         animal.call(this, name);
      }
      var dog1= new dog("旺财");
      console.log(dog1.getName()); // 旺财
    
    
      // 实例化方法继承的方式
      function Animal(){
        this.name= "animal";
        this.getName = function(name){
             return this.name;
        }
      }
      function Dog(){
        this.name ='汪汪'
      }
      var dog= new Dog();
      var animal = new Animal();
      console.log(animal.getName.call(dog, ","));
    
    
    // functionName.apply(作用域, 参数数组)
    
    function sun(num1, num2){
    
              return num1 - num2;
    
          }
    
          function cont(num1, num2){
    
              return sun.apply(this, [num1,num2]);  // 这两种都是可以的
    
              //return sun.apply(this, arguments);
    
          }
    
          console.log(cont(1,10)); // -9
    
    

    数字的处理 toFixed / toExponential / toPrecision

    //toFixed 
    var a =10;
    a.toFixed(2); // 10.00;
    // 常见问题,如果对数据的精度要求不是很高的情况下,我们解决 0.1+0.2 != 0.3 的情况
    Number((0.1+0.2).toFixed(2)) // 0.30
    
    // 采用科学计数法显示
    a.toExponential() // "1e+1"
    
    // 会根据传入的参数,自动的用科学计数法,还是正常的显示十进制    
    a.toPrecision(1) // 1e+1;
    
    

    字符方法 charAt、charCodeAt、concat、slice、substr、substring、toLowerCase、toLocaleLowerCase、toUpperCase、toLocaleUpperCase、fromCharCode、split

    var str = 'hello world';
    // 获取字符串中指定位置的字符
    str.charAt(1); //e
    
    // 获取指定位置字符的字符编码
    str.charCodeAt(); //101
    
    // 字符连接,当然后面是可以跟多个参数的。其实更多的时候我们是用 + 来实现字符串的链接
    str.concat(" and"," you "); //"hello world and you"
    
    //fromCharCode 的作用与 charCodeAt 方法效果是相反的。参数是字符和数字都可以,前提是能转换成整数
    Sting.fromCharCode(101); //e  
    
    // split 经常用来将 string 转换成 Array 类型。
    let a = "foo";
    let b = a.split("");
    b// ['f','o','o'];
    // 当然如果想对字符串的操作用 Array 的方法其实可以不用将字符串 split 转换
    1. 使用call
    Array.prototype.join.call(a,"-"); // f-o-o
    
    Array.prototype.map.call(a, (val) => {
        return val.toLocaleUpperCase()
    }).join(".")  // F.O.O
    
    

    replace 方法的使用

    //在以前的时候我都是仅仅简单的使用 replace 替换字符,其实我们可以对 ,替换的字符做一些操作
    
    // 可以给符合的字符增加字符并凭借在一起。
    var str = "bat, cat, dat";
    var word= str.replace(/(.at)/g, "word ($1)");
    alert(word);
    
    // 当然第二个参数也可以是一个方法,传入三个值
    // match:匹配的字符
    // originalText:被替换的字符
    // positoin:被替换字符的位置
    var word = str.replace(/(.at)/g, function(match, originalText, position){
        switch(match){
            case "bat" :
                return "bb "+position +' '+originalText;
            case "cat" :
                return "cc "+ position+ ' ' +originalText;
            case "dat" :
                return "dd "+ position +' '+ originalText;
        }
    })
    alert(word); // "bb 0 bat, cc 5 cat, dd 10 dat"
    
    
    
    获取匹配参数说明

    在数组中比较数字的大小

    // 方法一排序 sort
    var arr = [1,2,3,4];
    
    var arrsort = arr.sort(function(a, b){
      return b -a ; // return a-b; 升序
    })
    arrsort[0]; // 4
    
    //方法二: Math.max, Math.min 
    //语法: Math.max(num1,num2,num3...);  但是如果我是想比较数组里的值怎么办呢,这时候就可以用到 eval了
    var arr = [1,2,3,4];
    var arrStr = arr.toString();
    eval("Math.max("+ arrstr +")"); // 4
    
    // 方法三,利用 apply 第二参数可以接收数组的特性,然后结合Math.max & Math.min js 提供的 2 个方法
    var arr = [1,2,3,4];
    function max(arr){
        return Math.max.apply(Math,arr);  
    };
    max(arr); // 4
    
    // 方法 4 for 循环判断
    var arr = [1,2,3,4];
    function max(arr){
      var curr = "";
      for(var i in arr){
        if(arr[i] > curr ){
          curr = arr[i]
        }
      }
      return curr;
    }
    max(arr); // 4
    
     // 我知道的暂时就这四种,还缺少性能上的比较,后期看到了在更新。
    
    
    
    

    Math 方法

    // Math.max(num1, num2, num3 ...) 获取最大值
    // Math.min(num1, num2, num3 ...) 获取最小值
    // Math.ceil(num) // 执行向上舍入为最接近的整数
    // Math.floor(num) // 执行向下舍入最接近的整数
    // Math.round(num) // 执行标准的四舍五入,并且四舍五入小数后一位,只保留整数位置,和toFixed不同
    // Math.random() //返回一个 0 ~ 1 之间的随机数,不包括 0 和 1
    
    
    // 生成 0 - 9 的一个随机数
    Math.floor(Math.random() * 10);
    
    // 如果你想生成的 2 - 10 的一个随机数, 然后自己看半天蛮麻烦的。其实别人早已经想到方法了
    
    function selectFrom(lowerValue, upperValue){
      var choices = upperValue -  lowerValue;
      return  Math.floor(Math.random() * choices + lowerValue );
    }
    
    

    备注常见的问题

    • 解决 0.1 + 0.2 != 0.3 的情况
    // 精度要求不高的情况下
    Number((0.1+0.2).toFixed(2)) // 0.3
    // 判断一个特定值
    Number.EPSILON  // 2.220446049250313e-16
    if(a - b< Number.EPSILON){
      return true; // 相等
    }
    
    • 取小数的整数部分
    1、~~49.1 // 49
    2、~~-49.1 // -49
    3、 Number.parseInt(49.1) // 49
    
    • 在使用 == 判断对象和数字的情况
    let d = {
        val: 1
    }
    console.log(d ==1); // false
    
    let d = {
        val: 1,
        toString: function () {
            return this.val;
         },
    
    }
    console.log(d ==1); // false
    
    let d = {
        val: 1,
         toString: function () {
             return this.val;
         },
         valueOf: function () {
             return this.val + 1;
         }
    }
    console.log(d ==2); // true
    
    // 在使用 == 判断相等的时候,js 会将引用类型数据获取 ToPrimitive 对应的值,会调用 toString 和 ValueOf。
    
    • js 相等转换类型中的7个坑,真的是天坑。你会意想不到的,因为他们是相等的。
    false == "0"; // true -- 晕!
    false == 0; // true -- 晕!
    false == ""; // true -- 晕!
    false == []; // true -- 晕!
    "" == 0; // true -- 晕!
    "" == []; // true -- 晕!
    0 == []; // true -- 晕!
    
    • js switch 函数中 case 值的运用
    var a = "hello world";
    var b = 10;
    switch (true) {
        case (a || b == 10):
            // 永远执行不到这里
            console.log(123)
            break;
        default:
            console.log("Oops");
    }
    // 如果细微的更改下
    switch (true) {
        case !!(a || b == 10):
            console.log(123)
            break;
        default:
            console.log("Oops");
    }
    // 这里执行的结果就是 123, 这样书写仅做参考。
    

    备注

    • 所有的对象都有 toLocaleString() 、 toString() 、 valueOf() 方法。可以看到方法执行的内容,不过每个浏览器对这三个方法返回内容和格式会有一定的差异,对调试代码还是很有用的。
    • alert 方法只接收字符串的参数,当传入数组的时候,alert 会执行 toString() 方法,因此显示的结果是数组的字符串并以逗号隔开的形式。

    相关文章

      网友评论

          本文标题:ECMAScript 5 常用的技巧(一)

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