美文网首页
ES6 的 Set and Map

ES6 的 Set and Map

作者: Ailily | 来源:发表于2016-12-17 17:03 被阅读33次

    Map

    // map
    var m = new Map([['michael', 54],['lily', 32]])
    m.get('michael')  //54
    m.set('lily', 18)  
    m.get('lily') //18
    m.delete('lily')
    m.get('lily')   //undefined
    
    // Set和Map类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。
    var s = new Set([1, 2, 3])
    s.add(4)
    console.log(s) // [1, 2, 3, 4]
    s.delete(2)
    console.log(s) // [1, 3, 4]
    
    // 转换格式取值
    var m=new Map();
    var n=[['po',10],['sd',20],['cz',30],['bf',40],['as',50]];
    for(var i=0;i<n.length;i++){
    m.set(n[i][0],n[i][1])
    }
    var look=m.get('po');
    alert(look);
    
    // 可用于数组去重
    var arr = [1,2,1,2,2,1];
    //new Set 数组去重
    function unique(arr){
      return Array.from(new Set(arr));
    };
    //使用ES6的方法可以去重.
    console.log(unique(arr));
    

    Array.from的妙用

    es6新特性中Array类多了一个静态方法from,这个方法作用是将一个ArrayLike对象或者Iterable对象转换成一个Array,本文只讨论ArrayLike对象相关内容。

    Iterable

    遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。

    具有iterable类型的集合可以通过新的for ... of循环来遍历。

    高阶函数

    map/reduce

    arr.map((element, index, self) => ) arr.reduce((x, y) => )

    // 要把[1, 3, 5, 7, 9]变换成整数13579,reduce()也能派上用场:
    var arr = [1, 3, 5, 7, 9]
    arr.reduce((x, y) => x*10+y)
    
    // 请把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']。
    function normalize(arr){
      return arr.map((name) => name[0].toUpperCase() + name.substring(1).toLowerCase())
    }
    

    filter

    arr.filter((element, index, self) => )

    // filter 所需参数
    var arr = ['A', 'B', 'C'];
    var r = arr.filter(function (element, index, self) {
        console.log(element); // 依次打印'A', 'B', 'C'
        console.log(index); // 依次打印0, 1, 2
        console.log(self); // self就是变量arr
        return true;
    });
    
    // filter 去重
    var r,arr = ['apple', 'apple', 'pear', 'grape', 'banana'];
    r = arr.filter((element, index, self) => self.indexOf(element) === index)
    console.log(r)
    
    // 用filter()筛选出素数:
    function get_primes(arr) {
      return arr.filter(element =>element<2? false : !/^(11+?)\1+$/.test(Array(element + 1).join('1')));
    }
    
    function get_primes(arr) {
      return arr.filter(function (x) {
          if (x < 2) return false;
          for (var temp = 2; temp < x; temp++) {
              if (x % temp === 0) {
                  return false;
              }
          }
          return true;
      })
    }
    

    sort

    var arr = [10, 20, 1, 2];
    arr.sort(function (x, y) {
        if (x < y) {
            return 1;
        }
        if (x > y) {
            return -1;
        }
        return 0;
    }); // [20, 10, 2, 1]
    

    箭头函数的作用

    箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。

    var obj = {
      birth: 1990,
      getAge: function () {
        var b = this.birth // 1990
        var fn = function () {
          return new Date().getFullYear() - this.birth; //this指向window或undefined
        }
      }
    }
    

    现在,箭头函数完全修复了this的指向,this总是指向 词法作用域 ,也就是外层调用者obj:

    var obj = {
      birth: 1990,
      getAge: function () {
        var b = this.birth // 1990
        var fn = () => new Date().getFullYear() - this.birth
        return fn
      }
    }
    obj.getAge(); // 25
    

    由于this在箭头函数中已经按照 词法作用域 绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略:

    var obj = {
        birth: 1990,
        getAge: function (year) {
            var b = this.birth; // 1990
            var fn = (y) => y - this.birth; // this.birth仍是1990
            return fn.call({birth:2000}, year);
        }
    };
    obj.getAge(2015); // 25
    
    // method1 递归法 
    function aaa(n){
      if(n <= 2) return 1
      return aaa(n-1) + aaa(n-2)
    }
    
    // 迭代法 
    function aaa(n) {
      var num1 = 1
      var num2 = 1
      var num3 = 0
      for(var i=0;i < n-2;i++){
        num3 = num1 + num2
        num1 = num2
        num2 = num3
      }
      return num3
    }
    
    // 测试:
    fib(5); // [0, 1, 1, 2, 3]
    fib(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
    

    标准对象

    更细心的同学指出,number对象调用toString()报SyntaxError:

    123.toString(); // SyntaxError
    遇到这种情况,要特殊处理一下:
    
    123..toString(); // '123', 注意是两个点!
    12.3.toString();  // 12.3
    (123).toString(); // '123'
    

    Date

    你可能观察到了一个非常非常坑爹的地方,就是JavaScript的月份范围用整数表示是0~11,0表示一月,1表示二月……

    第二种创建一个指定日期和时间的方法是解析一个符合ISO 8601格式的字符串:

    var now = new Date();
    now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
    now.getFullYear(); // 2015, 年份
    now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
    now.getDate(); // 24, 表示24号
    now.getDay(); // 3, 表示星期三
    now.getHours(); // 19, 24小时制
    now.getMinutes(); // 49, 分钟
    now.getSeconds(); // 22, 秒
    now.getMilliseconds(); // 875, 毫秒数
    now.getTime(); // 1435146562875, 以number形式表示的时间戳
    
    var d = Date.parse('2015-06-24T19:49:22.875+08:00');
    d; // 1435146562875
    但它返回的不是Date对象,而是一个时间戳。不过有时间戳就可以很容易地把它转换为一个Date:
    
    var d = new Date(1435146562875);
    d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
    

    RegExp

    要匹配变长的字符,在正则表达式中,用 * 表示任意个字符(包括0个),用 + 表示至少一个字符,用 ? 表示0个或1个字符,用 {n} 表示n个字符,用 {n,m} 表示n-m个字符:

    来看一个复杂的例子: \d{3}\s+\d{3,8}

    我们来从左到右解读一下:

    1. \d{3} 表示匹配3个数字,例如 '010'

    2. \s 可以匹配一个空格(也包括Tab等空白符),所以 \s+ 表示至少有一个空格,例如匹配 ' ''\t\t' 等;

    3. \d{3,8} 表示3-8个数字,例如 '1234567'

    综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。

    如果要匹配 '010-12345' 这样的号码呢?由于 '-' 是特殊字符,在正则表达式中,要用 '\' 转义,所以,上面的正则是 \d{3}\-\d{3,8}

    但是,仍然无法匹配 '010 - 12345' ,因为带有空格。所以我们需要更复杂的匹配方式。

    进阶

    要做更精确地匹配,可以用 [] 表示范围,比如:

    • [0-9a-zA-Z\_] 可以匹配一个数字、字母或者下划线;

    • [0-9a-zA-Z\_]+ 可以匹配至少由一个数字、字母或者下划线组成的字符串,比如 'a100''0_Z''js2015' 等等;

    • [a-zA-Z\_\$][0-9a-zA-Z\_\$]* 可以匹配由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$组成的字符串,也就是JavaScript允许的变量名;

    • [a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19} 更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

    A|B 可以匹配A或B,所以 (J|j)ava(S|s)cript 可以匹配 'JavaScript''Javascript''javaScript' 或者 'javascript'

    ^ 表示行的开头, ^\d 表示必须以数字开头。

    $ 表示行的结束, \d$ 表示必须以数字结束。

    你可能注意到了, js 也可以匹配 'jsp' ,但是加上 ^js$ 就变成了整行匹配,就只能匹配 'js' 了。

    切分字符串

    用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码:

    'a b   c'.split(' '); // ['a', 'b', '', '', 'c']
    

    嗯,无法识别连续的空格,用正则表达式试试:

    'a b   c'.split(/\s+/); // ['a', 'b', 'c']
    

    无论多少个空格都可以正常分割。加入 , 试试:

    'a,b, c  d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd']
    

    再加入 ; 试试:

    'a,b;; c  d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']
    

    如果用户输入了一组标签,下次记得用正则表达式来把不规范的输入转化成正确的数组。

    验证 邮箱 试试:

    var re = / ^\w+[.]?\w+@\w+.\w+$ /;

    var re = / ^\w+.?\w+@\w+.\w+$ /;

    var re = / (<\w+\s\w+?>)\s(\w+.?\w+@\w+.\w+) /;

    相关文章

      网友评论

          本文标题: ES6 的 Set and Map

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