zoukankan      html  css  js  c++  java
  • ES6

    Set和Map是ES6中新增的数据结构,Set是集合,无序唯一,Map类似于对象,也是"key-value"形式,但是key不局限于字符串。

    1.Set的用法

    Set是构造函数,可以使用new初始化一个Set实例,如下所示

    var set = new Set();
    set.add(2);
    set.add(2);
    set.add(3);
    set.add('hello');
    console.log(set,set.size);
    //也可以使用数组或类数组作为参数进行初始化
    var s1 = new Set([2,3,4,2,3,10]);
    console.log(s1,s1.size);
    Set [ 2, 3, "hello" ] 3
    Set [ 2, 3, 4, 10 ] 4

    Set集合具有唯一性,因此不管是向Set中添加重复的元素还是使用数组作为参数,都会自动剔除重复的元素(内部使用的是等值算法),包括NaN,(+0,-0)。因此数组去重的功能可以借助这个特性来做,如下所示

    var arr_unique = arr => [...new Set(arr)];//这里使用Array.from方法一样,Array.from(new Set(arr))
    console.log(arr_unique([3,3,4,5,6,6,NaN,NaN,+0,-0]));
    Array [ 3, 4, 5, 6, NaN, 0 ]

    但是两个对象总是不相等,因此它们的内存地址不同。

    Set的实例方法和属性

    属性有size,constructor,size记录Set实例的元素总数,constructor指向Set构造函数,即Set函数,如下所示

    var s = new Set([1,2,3]);
    console.log(s.size);
    console.log(Object.is(s.constructor,Set));
    3
    true

    方法可以分为两类:操作方法和遍历方法。操作方法有add,delete,has,clear,用法如下所示

    var s2 = new Set();
    s2.add(1);//add添加元素
    s2.add(2);
    s2.add('hello');
    console.log(s2.size);
    s2.delete(2);//delete删除指定元素
    console.log(s2.size,s2);
    console.log(s2.has(2));//has判断指定元素是否存在
    s2.clear();//clear清空所有元素
    console.log(s2.size,s2);
    3
    2 Set [ 1, "hello" ]
    false
    0 Set [  ]

    遍历方法有keys,values,entries,forEach,用法如下所示

    var s3 = new Set([2,'hello']);
    var keys = s3.keys(),
        values = s3.values(),
        entries = s3.entries();
    //由于Set没有键名,只有键值,故keys和values是一样的效果
    for(let x of keys){
        console.log(x);
    }
    for(let x of values){
        console.log(x);
    }
    for(let x of entries){
        console.log(x);
    }
    //Set的默认迭代器就是values,因此可以对Set直接使用for..of遍历
    console.log(s3[Symbol.iterator] === s3.values);
    for(let x of s3){
        console.log(x);
    }
    2
    hello
    2
    hello
    Array [ 2, 2 ]
    Array [ "hello", "hello" ]
    true
    2
    hello

    2.WeakSet

    WeakSet与Set类似,只不过前者只存放对象,且是弱引用。WeakSet实例不可遍历,没有size属性。用法如下

    var ws = new WeakSet();
    var obj = {};
    var foo = {};
    
    ws.add(window);
    ws.add(obj);
    
    console.log(ws.has(window));
    console.log(ws.has(obj)); 
    
    ws.delete(window);
    console.log(ws.has(window));   
    
    true
    true
    false

    3.Map

    Map类似Object,也是"key-value"的集合,但是Map的键值不限于字符串,如下所示

    var map = new Map();
    var obj = {};
    map.set(obj,"hello");
    console.log(map.get(obj));
    hello

    Map也接收一个数组作为参数,数组的成员将变成Map的成员,数组的元素必须是类似key-valye的形式,如下所示

    var arr1 = [2,3,4];
    var m1 = new Map(arr1);
    TypeError: iterable for Map should have array-like objects
    //arr1数组的元素不是key-value形式的,故报错
    var arr2 = [['name','xiaoming'],['age',20]];
    var m2 = new Map(arr2);
    console.log(m2.size);
    console.log(m2.get("name"),m2.get("age"));
    2
    xiaoming 20

    对同一个键值进行多次的赋值,较后的赋值会覆盖以前的值,且读取一个不存在的键,会返回undefined,如下所示

    var arr2 = [['name','xiaoming'],['age',20]];
    var m2 = new Map(arr2);
    console.log(m2.size);
    console.log(m2.get("name"),m2.get("age"));
    m2.set('name','zhangsan');
    console.log(m2.get('name'));
    console.log(m2.get('dsdsdsds'));
    2
    xiaoming 20
    zhangsan
    undefined

    如果键值不是基本数据类型,而是引用类型的话,对同一对象的引用才会被认为是同一键值(NaN与NaN,+0与-0被视为相同的键),如下所示

    var myMap = new Map();
    var o = {};
    myMap.set(o,"hello");
    console.log(myMap.get(o));
    myMap.set({x:1},"world");
    console.log(myMap.get({x:1}));
    myMap.set(NaN,"NaN");
    myMap.get(NaN);
    
    hello
    undefined
    "NaN"

    Map实例的属性和方法

    属性有size,constructor:size记录Map键值对数量,constructor指向Map

    方法也分为两大类:操作方法和遍历方法,操作方法有set,get,has,delete,clear等,用法如下所示

    var m = new Map();
    m.set('name','lisi');
    m.set('age',20);
    console.log(m.get('name'));
    console.log(m.has('name'));
    m.delete('name');
    console.log(m.has('name'));
    m.clear();
    console.log(m.has('age'));
    lisi
    true
    false
    false

    遍历方法有keys,values,entries,forEach等,用法如下所示

    var m = new Map();
    m.set('name','lisi');
    m.set('age',20);
    for(let key of m.keys()){
        console.log(key);
    }
    for(let value of m.values()){
        console.log(value);
    }
    for(let [key,value] of m.entries()){
        console.log(key+':'+value);
    }
    console.log(Map.prototype[Symbol.iterator] === Map.prototype.entries);//Map的默认遍历器是entries
    for(let [key,value] of m){
        console.log(key+':'+value);
    }
    m.forEach( (value,key) => console.log(key+':'+value));
    name
    age
    lisi
    20
    name:lisi
    age:20
    true
    name:lisi
    age:20
    name:lisi
    age:20

    利用扩展运算符可以快速将Map转换成数组,因此可以利用数组的特性为Map实例添加一些方法,如map,filter等,如下所示

    var m = new Map();
    m.set('name','lisi');
    m.set('age',20);
    Map.prototype.filter = function(operatefun){
        return new Map([...this].filter(operatefun));
    };
    console.log(m.filter(([key,value])=>key!='age'));
    
    Map.prototype.map = function(operatefun){
        return new Map([...this].map(operatefun));
    };
    console.log(m.map(([key,value]) =>[key+'_new',value+'_new']));
    Map { name: "lisi" }
    Map { name_new: "lisi_new", age_new: "20_new" }

    4.WeakMap

    WeakMap类似于Map,但是只能使用对象作为键值名,其用法如下所示

    var weakMap = new WeakMap();
    var obj = {x:1};
    weakMap.set('name','xiaoming');
    TypeError: "name" is not a non-null object
    ------------------------------------------------------
    var weakMap = new WeakMap();
    var obj = {x:1};
    weakMap.set(obj,'hello');
    weakMap.get(obj);
    "hello"

    WeakMap的更多用法这里就不赘述了,感兴趣的同学可以自行查看相关文档。

  • 相关阅读:
    leetcode 141. Linked List Cycle
    leetcode 367. Valid Perfect Square
    leetcode150 Evaluate Reverse Polish Notation
    小a与星际探索
    D. Diverse Garland
    C. Nice Garland
    数的划分(动态规划)
    平衡二叉树(笔记)
    1346:【例4-7】亲戚(relation)
    1192:放苹果(dp + 搜索)
  • 原文地址:https://www.cnblogs.com/zmxmumu/p/5601368.html
Copyright © 2011-2022 走看看