ES6 温故知新 Set & Map

Set

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

Set 在 ES6 中的定义:

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

通过 new 创建一个 Set 集合:

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

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

interface Set {
    add(value: T): this;
    clear(): void;
    delete(value: T): boolean;
    forEach(callbackfn: (value: T, value2: T, set: Set) => 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 (values?: readonly T[] | null): WeakSet;
    readonly prototype: WeakSet;
}
 
 

定义一个 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 {
    add(value: T): this;
    delete(value: T): boolean;
    has(value: T): boolean;
}

WeakSet 有三个方法:

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

Map

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

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 {
    clear(): void;
    delete(key: K): boolean;
    forEach(callbackfn: (value: V, key: K, map: Map) => 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 (entries?: readonly [K, V][] | null): WeakMap;
    readonly prototype: WeakMap;
}

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

interface WeakMap {
    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)