ES6 温故知新 Set & Map

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}')
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容