Open Twlig opened 2 years ago
Map 是一种新的集合类型,是真正的键/值存储机制。
const m = new Map();
// 使用嵌套数组初始化映射 const m1 = new Map([ ["key1", "val1"], ["key2", "val2"], ["key3", "val3"] ]); alert(m1.size); // 3 // 使用自定义迭代器初始化映射 const m2 = new Map({ [Symbol.iterator]: function*() { yield ["key1", "val1"]; yield ["key2", "val2"]; yield ["key3", "val3"]; } }); alert(m2.size); // 3 // 映射期待的键/值对,无论是否提供 const m3 = new Map([[]]); alert(m3.has(undefined)); // true alert(m3.get(undefined)); // undefined
size
获取Map实例映射的键值对数量
alert(m1.size); // 3
has()
判断是否存在该键。传入一个参数,返回布尔值。
Map 内部使用 SameValueZero 比较操作(ECMAScript 规范内部定义,语言中不能使用),基本上相当于使用严格对象相等的标准来检查键的匹配性。
m1.has("key1") //true
set()
添加键/值对。
接收两个参数:参数一键,参数二值。
set()方法返回映射实例,因此可以把多个操作连缀起来,包括初始化声明。
const m = new Map() .set("firstName", "Matt") .set("lastName", "Frisbie");
get()
查询键对应的值。接收一个参数:待查询的键。使用 SameValueZero 比较操作。
m.get("firstName") //Matt
delete()
删除键对应的键值对。接收一个参数:待删除的键。使用 SameValueZero 比较操作。
m.delete("firstName"); //m : {'lastName' => 'Frisbie'}
clear()
清除映射中的所有键值对。
m.clear() //Map(0)
Map映射实例可以提供一个迭代器(Iterator),能以插入顺序生成[key, value]形式的数组。可以通过 entries()方法或者 Symbol.iterator 属性取得这个迭代器。
Symbol.iterator 属性
const m = new Map([ ["key1", "val1"], ["key2", "val2"], ["key3", "val3"] ]); for (let pair of m[Symbol.iterator]()) { alert(pair); } // [key1,val1] // [key2,val2] // [key3,val3]
entries()
for (let pair of m.entries()) { alert(pair); } // [key1,val1] // [key2,val2] // [key3,val3]
keys()、values()
for (let key of m.keys()) { alert(key); } // key1 // key2 // key3 for (let key of m.values()) { alert(key); } // value1 // value2 // value3
✨注意:
键是对象的话,属性是可以修改的,映射关系不会变。如果是字符串、数字等就不能修改,没有修改的接口。
const keyObj = {id: 1}; const m = new Map([ [keyObj, "val1"] ]); // 修改了作为键的对象的属性,但对象在映射内部仍然引用相同的值 for (let key of m.keys()) { key.id = "newKey"; alert(key); // {id: "newKey"} alert(m.get(keyObj)); // val1 键值对的映射关系没变 } alert(keyObj); // {id: "newKey"}
“弱映射”(WeakMap)是一种新的集合类型,其 API 也是 Map 的子集。“weak”(弱)指的是 JavaScript 垃圾回收程序对待“弱映射”中键的方式。
弱映射中的键只能是 Object 或者继承自 Object 的类型
尝试使用非对象设置键会抛出TypeError
值的类型没有限制
只要键存在,键/值对就会存在于映射中,该键值对就不会被当作垃圾回收
键指向的对象后续不存在了,键值对就会在映射中被垃圾回收
不可迭代
WeakMap只有set,get,has,delete方法。没有迭代能力,其不可能在不知道对象引用的情况下从弱映射中取得值。当然也就没有clear方法。
const wm = new WeakMap(); wm.set({}, "val");
const wm = new WeakMap(); const container = { key: {} }; wm.set(container.key, "val"); function removeReference() { container.key = null; }
container.key -> "val"
因为 WeakMap 实例不会妨碍垃圾回收,所以非常适合保存关联元数据。
const wm = new WeakMap(); const loginButton = document.querySelector('#login'); // 给这个节点关联一些元数据 wm.set(loginButton, {disabled: true});
当节点从 DOM 树中被删除后,垃圾回收程序就可以立即释放其内存(假设没有其他地方引用这个对象)。回收loginButton以及对应的弱映射中的键值对。如果采用Map,则loginButton和对应的键值对会一直存在。
✨小结:
WeakMap主要的用途就是便于垃圾回收,由于WeakMap中对键的引用是弱引用,不会阻止垃圾回收,所以当键指向的对象不在了(即没有除WeakMap外的其他变量引用该对象),WeakMap中的键值对映射关系也就销毁了。
Set 是一种新集合类型。
const s = new Set();
// 使用数组初始化集合 const s1 = new Set(["val1", "val2", "val3"]); alert(s1.size); // 3 // 使用自定义迭代器初始化集合 const s2 = new Set({ [Symbol.iterator]: function*() { yield "val1"; yield "val2"; yield "val3"; } });
获取集合元素数量
alert(s1.size); // 3
判断是否存在该元素。传入一个参数,返回布尔值。
使用 SameValueZero 比较操作(ECMAScript 规范内部定义,语言中不能使用),基本上相当于使用严格对象相等的标准来检查键的匹配性。
s1.has("val1") //true
add()
添加元素。
add()方法返回集合实例,因此可以把多个操作连缀起来,包括初始化声明。
const s = new Map() .add("val1") .add("val2");
删除元素。使用 SameValueZero 比较操作。返回一个布尔值,表示集合中是否存在要删除的值。
s.delete("val1");
销毁集合实例中的所有值。
s.clear()
集合实例可以提供一个迭代器(Iterator),能以插入顺序生成集合内容。可以通过 values()方法及其别名方法 keys()(或者 Symbol.iterator 属性,它引用 values())取得这个迭代器。
const s = new Set(["val1", "val2", "val3"]); for (let value of s[Symbol.iterator]()) { alert(value); } // val1 // val2 // val3
for (let value of s.keys()) { alert(key); } // val1 // val2 // val3 for (let value of s.values()) { alert(value); } // val1 // val2 // val3
集合的 entries()方法返回一个迭代器,可以按照插入顺序产生包含两个元素的数组,这两个元素是集合中每个值的重复出现
const s = new Set(["val1", "val2", "val3"]); for (let pair of s.entries()) { console.log(pair); } // ["val1", "val1"] // ["val2", "val2"] // ["val3", "val3"]
“弱集合”(WeakSet)是一种新的集合类型。WeakSet 中的“weak”(弱),描述的是 JavaScript 垃圾回收程序对待“弱集合”中值的方式。这些值不属于正式的引用,不会阻止垃圾回收。
弱集合中的值只能是 Object 或者继承自 Object 的类型
尝试使用非对象设置值会抛出 TypeError
集合中对象的没有引用之后,会被垃圾回收,从集合中消失
有add,has,delete方法,没有clear方法。
const ws = new WeakSet(); ws.add({});
add()方法初始化了一个新对象,并将它用作一个值。因为没有指向这个对象的其他引用,所以当这行代码执行完成后,这个对象值就会被当作垃圾回收。然后,这个值就从弱集合中消失了,使其成为一个空集合。
const ws = new WeakSet(); const container = { val: {} }; ws.add(container.val); function removeReference() { container.val = null; }
这一次,container 对象维护着一个对弱集合值的引用,因此这个对象值不会成为垃圾回收的目标。不过,如果调用了 removeReference(),就会摧毁值对象的最后一个引用,垃圾回收程序就可以把这个值清理掉。
加入对应集合,给节点打上“禁用”标签。通过查询元素在不在 disabledElements 中,就可以知道它是不是被禁用了。只要 WeakSet 中任何元素从 DOM 树中被删除,垃圾回收程序就可以忽略其存在,而立即释放其内存(假设没有其他地方引用这个对象)
const disabledElements = new WeakSet(); const loginButton = document.querySelector('#login'); // 通过加入对应集合,给这个节点打上“禁用”标签 disabledElements.add(loginButton);
Map
Map 是一种新的集合类型,是真正的键/值存储机制。
初始化
空映射
可迭代对象创建映射
实例方法
size
获取Map实例映射的键值对数量
has()
判断是否存在该键。传入一个参数,返回布尔值。
Map 内部使用 SameValueZero 比较操作(ECMAScript 规范内部定义,语言中不能使用),基本上相当于使用严格对象相等的标准来检查键的匹配性。
set()
添加键/值对。
接收两个参数:参数一键,参数二值。
set()方法返回映射实例,因此可以把多个操作连缀起来,包括初始化声明。
get()
查询键对应的值。接收一个参数:待查询的键。使用 SameValueZero 比较操作。
delete()
删除键对应的键值对。接收一个参数:待删除的键。使用 SameValueZero 比较操作。
clear()
清除映射中的所有键值对。
迭代
Map映射实例可以提供一个迭代器(Iterator),能以插入顺序生成[key, value]形式的数组。可以通过 entries()方法或者 Symbol.iterator 属性取得这个迭代器。
Symbol.iterator 属性
entries()
keys()、values()
✨注意:
键是对象的话,属性是可以修改的,映射关系不会变。如果是字符串、数字等就不能修改,没有修改的接口。
WeakMap
“弱映射”(WeakMap)是一种新的集合类型,其 API 也是 Map 的子集。“weak”(弱)指的是 JavaScript 垃圾回收程序对待“弱映射”中键的方式。
特性
弱映射中的键只能是 Object 或者继承自 Object 的类型
尝试使用非对象设置键会抛出TypeError
值的类型没有限制
只要键存在,键/值对就会存在于映射中,该键值对就不会被当作垃圾回收
键指向的对象后续不存在了,键值对就会在映射中被垃圾回收
不可迭代
实例方法
WeakMap只有set,get,has,delete方法。没有迭代能力,其不可能在不知道对象引用的情况下从弱映射中取得值。当然也就没有clear方法。
案例说明
container.key -> "val"
在WeakMap的键值对映射存在,不会被垃圾回收container.key -> "val"
在WeakMap中的键值对映射就会垃圾回收。应用场景
DOM 节点元数据
因为 WeakMap 实例不会妨碍垃圾回收,所以非常适合保存关联元数据。
当节点从 DOM 树中被删除后,垃圾回收程序就可以立即释放其内存(假设没有其他地方引用这个对象)。回收loginButton以及对应的弱映射中的键值对。如果采用Map,则loginButton和对应的键值对会一直存在。
✨小结:
WeakMap主要的用途就是便于垃圾回收,由于WeakMap中对键的引用是弱引用,不会阻止垃圾回收,所以当键指向的对象不在了(即没有除WeakMap外的其他变量引用该对象),WeakMap中的键值对映射关系也就销毁了。
Set
Set 是一种新集合类型。
初始化
空集合
可迭代对象创建
实例方法
size
获取集合元素数量
has()
判断是否存在该元素。传入一个参数,返回布尔值。
使用 SameValueZero 比较操作(ECMAScript 规范内部定义,语言中不能使用),基本上相当于使用严格对象相等的标准来检查键的匹配性。
add()
添加元素。
add()方法返回集合实例,因此可以把多个操作连缀起来,包括初始化声明。
delete()
删除元素。使用 SameValueZero 比较操作。返回一个布尔值,表示集合中是否存在要删除的值。
clear()
销毁集合实例中的所有值。
迭代
集合实例可以提供一个迭代器(Iterator),能以插入顺序生成集合内容。可以通过 values()方法及其别名方法 keys()(或者 Symbol.iterator 属性,它引用 values())取得这个迭代器。
Symbol.iterator 属性
keys()、values()
entries()
集合的 entries()方法返回一个迭代器,可以按照插入顺序产生包含两个元素的数组,这两个元素是集合中每个值的重复出现
WeakSet
“弱集合”(WeakSet)是一种新的集合类型。WeakSet 中的“weak”(弱),描述的是 JavaScript 垃圾回收程序对待“弱集合”中值的方式。这些值不属于正式的引用,不会阻止垃圾回收。
特性
弱集合中的值只能是 Object 或者继承自 Object 的类型
尝试使用非对象设置值会抛出 TypeError
集合中对象的没有引用之后,会被垃圾回收,从集合中消失
不可迭代
实例方法
有add,has,delete方法,没有clear方法。
案例说明
add()方法初始化了一个新对象,并将它用作一个值。因为没有指向这个对象的其他引用,所以当这行代码执行完成后,这个对象值就会被当作垃圾回收。然后,这个值就从弱集合中消失了,使其成为一个空集合。
这一次,container 对象维护着一个对弱集合值的引用,因此这个对象值不会成为垃圾回收的目标。不过,如果调用了 removeReference(),就会摧毁值对象的最后一个引用,垃圾回收程序就可以把这个值清理掉。
使用场景
加入对应集合,给节点打上“禁用”标签。通过查询元素在不在 disabledElements 中,就可以知道它是不是被禁用了。只要 WeakSet 中任何元素从 DOM 树中被删除,垃圾回收程序就可以忽略其存在,而立即释放其内存(假设没有其他地方引用这个对象)