Map


创建

  1. const m = new Map();

初始化实例

  1. // 使用嵌套数组初始化映射
  2. const m1 = new Map([
  3. ["key1", "val1"],
  4. ["key2", "val2"],
  5. ["key3", "val3"]
  6. ]);
  7. alert(m1.size); // 3

set()方法添加键/值

  1. m.set("firstName", "Matt")
  2. .set("lastName", "Frisbie");

get()方法,获取某个键的值

  1. console.log(m1.get("111"))

has()方法,判断某个键是否存在于map中

  1. console.log(m1.has("111"))

顺序与迭代

entries()方法

  1. const m = new Map([
  2. ["key1", "val1"],
  3. ["key2", "val2"],
  4. ["key3", "val3"]
  5. ]);
  6. alert(m.entries === m[Symbol.iterator]); // true
  7. for (let pair of m.entries()) {
  8. alert(pair);
  9. }
  10. // [key1,val1]
  11. // [key2,val2]
  12. // [key3,val3]

可以直接对映射实例使用扩展操作,把映射转换为数组

  1. const m = new Map([
  2. ["key1", "val1"],
  3. ["key2", "val2"],
  4. ["key3", "val3"]
  5. ]);
  6. console.log([...m]); // [[key1,val1],[key2,val2],[key3,val3]]

回调方式

映射的 forEach(callback, opt_thisArg)方法并传入回调,依次迭代每个键/值对

  1. const m = new Map([
  2. ["key1", "val1"],
  3. ["key2", "val2"],
  4. ["key3", "val3"]
  5. ]);
  6. m.forEach((val, key) => alert(`${key} -> ${val}`));
  7. // key1 -> val1
  8. // key2 -> val2
  9. // key3 -> val3

WeakMap

WeakMap 中的“weak”(弱),描述的是 JavaScript 垃圾回收程序对待“弱映射”中键的方式
特点是不会生成指向某个对象的引用

初始化

弱映射中的键只能是 Object 或者继承自 Object 的类型

  1. const wm = new WeakMap();

原始值可以先包装成对象再用作键

  1. const stringKey = new String("key1");
  2. const wm3 = new WeakMap([
  3. stringKey, "val1"
  4. ]);
  5. alert(wm3.get(stringKey)); // "val1"

初始化之后可以使用 set()再添加键/值对,可以使用 get()和 has()查询,还可以使用 delete()删除

弱键

  1. const wm = new WeakMap();
  2. const container = {
  3. key: {}
  4. };
  5. wm.set(container.key, "val");
  6. function removeReference() {
  7. container.key = null;
  8. }

上面代码并没生成指向key的引用,所以当removeReference()执行时,就会摧毁最后一个引用,垃圾回收程序就把这个键/值对清理掉了。

使用若映射

  1. const m = new Map();
  2. const loginButton = document.querySelector('#login');
  3. // 给这个节点关联一些元数据
  4. m.set(loginButton, {disabled: true});

上面代码使用常规的map,执行后,登录的按钮会从DOM树删除了,但由于映射中还保存着按钮的引用,内存中并未删除这个DOM节点

  1. const wm = new WeakMap();
  2. const loginButton = document.querySelector('#login');
  3. // 给这个节点关联一些元数据
  4. wm.set(loginButton, {disabled: true});

使用weakmap则会立即释放内存

Set

Set 在很多方面都像是加强的 Map

基本API

  1. const m = new Set();
  1. // 使用数组初始化集合
  2. const s1 = new Set(["val1", "val2", "val3"]);
  3. alert(s1.size); // 3
  4. // 使用自定义迭代器初始化集合
  5. const s2 = new Set({
  6. [Symbol.iterator]: function*() {
  7. yield "val1";
  8. yield "val2";
  9. yield "val3";
  10. }
  11. });
  12. alert(s2.size); // 3
  • add()增添值
  • has()查询
  • 通过 size 取得元素数量
  • 使用 delete()和 clear()删除元素
  • add()返回集合的实例,所以可以将多个添加操作连缀起来,包括初始化

顺序与迭代

集合实例可以提供一个迭代器(Iterator),能以插入顺序生成集合内容。

  1. const s = new Set(["val1", "val2", "val3"]);
  2. alert(s.values === s[Symbol.iterator]); // true
  3. alert(s.keys === s[Symbol.iterator]); // true
  4. for (let value of s.values()) {
  5. alert(value);
  6. }
  7. // val1
  8. // val2
  9. // val3
  10. for (let value of s[Symbol.iterator]()) {
  11. alert(value);
  12. }
  13. // val1
  14. // val2
  15. // val3

values()是默认迭代器

  1. const s = new Set(["val1", "val2", "val3"]);
  2. console.log([...s]); // ["val1", "val2", "val3"]

Weakset

与Map和Weakmap的区别几乎一样,不再赘述


迭代与扩展操作

4 种原生集合类型定义了默认迭代器
这意味着上述所有类型都支持顺序迭代,都可以传入 for-of 循环

  1. let iterableThings = [
  2. Array.of(1, 2),
  3. typedArr = Int16Array.of(3, 4),
  4. new Map([[5, 6], [7, 8]]),
  5. new Set([9, 10])
  6. ];
  7. for (const iterableThing of iterableThings) {
  8. for (const x of iterableThing) {
  9. console.log(x);
  10. }
  11. }
  12. // 1
  13. // 2
  14. // 3
  15. // 4
  16. // [5, 6]
  17. // [7, 8]
  18. // 9
  19. // 10

这些类型都兼容扩展操作符,执行浅复制

  1. let arr1 = [1, 2, 3];
  2. let arr2 = [...arr1];
  3. console.log(arr1); // [1, 2, 3]
  4. console.log(arr2); // [1, 2, 3]
  5. console.log(arr1 === arr2); // false

对于期待可迭代对象的构造函数

  1. let map1 = new Map([[1, 2], [3, 4]]);
  2. let map2 = new Map(map1);
  3. console.log(map1); // Map {1 => 2, 3 => 4}
  4. console.log(map2); // Map {1 => 2, 3 => 4}

构建数组的部分元素

  1. let arr1 = [1, 2, 3];
  2. let arr2 = [0, ...arr1, 4, 5];
  3. console.log(arr2); // [0, 1, 2, 3, 4, 5]

浅复制意味着只会复制对象引用:

  1. let arr1 = [{}];
  2. let arr2 = [...arr1];
  3. arr1[0].foo = 'bar';
  4. console.log(arr2[0]); // { foo: 'bar' }