美文网首页
ES6 温故知新 Set & Map

ES6 温故知新 Set & Map

作者: 滑天下之大稽 | 来源:发表于2020-02-23 18:16 被阅读0次

    Set

    ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

    Set 在 ES6 中的定义:

    interface SetConstructor {
        new <T = any>(values?: readonly T[] | null): Set<T>;
        readonly prototype: Set<any>;
    }
    declare var Set: SetConstructor;
    

    通过 new 创建一个 Set 集合:

    const s = new Set();
    const s = new Set([1, 2, 3, 4]);
    

    Set 接受一个由任意类型的数组作为参数,一个Set集合。

    interface Set<T> {
        add(value: T): this;
        clear(): void;
        delete(value: T): boolean;
        forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void;
        has(value: T): boolean;
        readonly size: number;
    }
    
    1. 方法:
      • add 添加某个值,返回 set 本身;
      • clear 清空 set 所有元素,没有返回值;
      • delete 删除某个值,返回一个 boolean,表示删除是否成功;
      • has 返回一个布尔值,表示set 是否有该成员;
    2. 属性:
      • size 返回 set 实例的成员总数。

    WeakSet

    WeakSet 结构与 Set 类似,也是不重复的值的集合。但是WeakSet 的成员只能是复杂类型的值(或继承自 object)。

    WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

    interface WeakSetConstructor {
        new <T extends object = object>(values?: readonly T[] | null): WeakSet<T>;
        readonly prototype: WeakSet<object>;
    }
    

    定义一个 WeakSet

    const ws = new WeakSet();
    const ws = new WeakSet([[1, 2], [3, 4]]);
    ws.add(1); // TypeError: Invalid value used in weak set
    

    WeakSet 没有 size 属性,没有办法遍历它的成员。

    interface WeakSet<T extends object> {
        add(value: T): this;
        delete(value: T): boolean;
        has(value: T): boolean;
    }
    

    WeakSet 有三个方法:

    • add 向 weakset 中增加一个新成员。
    • delete 清除 WeakSet 实例的指定成员。
    • has 返回一个布尔值,表示某个值是否在 WeakSet 实例之中。

    Map

    interface MapConstructor {
        new(): Map<any, any>;
        new<K, V>(entries?: readonly (readonly [K, V])[] | null): Map<K, V>;
        readonly prototype: Map<any, any>;
    }
    

    Map 类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

    const m = new Map();
    const o = {p: 'Hello World'};
    
    m.set(o, 'content') // 使用o作为Map的一个键值,其value是‘content’
    m.get(o) // "content"
    
    m.has(o) // true
    m.delete(o) // true
    m.has(o) // false
    
    interface Map<K, V> {
        clear(): void;
        delete(key: K): boolean;
        forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
        get(key: K): V | undefined;
        has(key: K): boolean;
        set(key: K, value: V): this;
        readonly size: number;
    }
    
    1. Map 的属性:
      • size 返回 Map 结构的成员总数。
    2. Map 的方法:
      • clear 清楚 Map 所有的成员,返回空;
      • delete 删除Map 指定 Key 的成员,返回是否删除成功;
      • get 获取指定 Key 的成员的 Value,没有该 Key 则返回 undefined
      • has 方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
      • set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。
    • Map.prototype.keys():返回键名的遍历器。
    • Map.prototype.values():返回键值的遍历器。
    • Map.prototype.entries():返回所有成员的遍历器。
    • Map.prototype.forEach():遍历 Map 的所有成员。

    WeakMap

    WeakMap 与 Map 类似,但是WeakMap只接受对象作为键名

    interface WeakMapConstructor {
        new <K extends object = object, V = any>(entries?: readonly [K, V][] | null): WeakMap<K, V>;
        readonly prototype: WeakMap<object, any>;
    }
    

    WeakMapMap 在 API 上的区别主要是两个,一是没有遍历操作(即没有keys()values()entries()方法),也没有size属性。

    interface WeakMap<K extends object, V> {
        delete(key: K): boolean;
        get(key: K): V | undefined;
        has(key: K): boolean;
        set(key: K, value: V): this;
    }
    
    • delete 删除Map 指定 Key 的成员,返回是否删除成功;
    • get 获取指定 Key 的成员的 Value,没有该 Key 则返回 undefined
    • has 方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
    • set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。

    Map 与其他值的互相转换:

    1. Map => Array: 使用扩展运算符...

      const m = new Map().set(true, 7).set({foo: 3}, ['abc']);
      [...m]
      // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
      
    2. Array => Map: 将数组传入 Map 构造函数,就可以转为 Map。

    3. Map => Object:如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名。

      function mapToObj(m) {
        let obj = Object.create(null);
        for (let [k,v] of m) {
          obj[k] = v
        }
        return obj
      }
      
      const myMap = new Map()
        .set('yes', true)
        .set('no', false);
      
      console.log(mapToObj(myMap));
      //  { yes: true, no: false }
      
    4. Object => Map:

      let obj = {"a":1, "b":2};
      let map = new Map(Object.entries(obj));
      
    5. Map => JSON:

      1. Key 都为 字符串

        function strMapToJson(strMap) {
          return JSON.stringify(strMapToObj(strMap));
        }
        
        let myMap = new Map().set('yes', true).set('no', false);
        strMapToJson(myMap)
        // '{"yes":true,"no":false}'
        
      2. Key 为其他值

        function mapToArrayJson(map) {
          return JSON.stringify([...map]);
        }
        
        let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
        mapToArrayJson(myMap)
        // '[[true,7],[{"foo":3},["abc"]]]'
        
    6. JSON => Map:

      function jsonToStrMap(jsonStr) {
        return objToStrMap(JSON.parse(jsonStr));
      }
      
      jsonToStrMap('{"yes": true, "no": false}')
      

    相关文章

      网友评论

          本文标题:ES6 温故知新 Set & Map

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