Skip to content

Commit 4de0cd6

Browse files
committed
docs(set): edit WeakMap
1 parent 88930c1 commit 4de0cd6

File tree

1 file changed

+22
-17
lines changed

1 file changed

+22
-17
lines changed

docs/set-map.md

+22-17
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,19 @@ wm.get(key)
983983

984984
上面代码中,键值`obj`是正常引用。所以,即使在 WeakMap 外部消除了`obj`的引用,WeakMap 内部的引用依然存在。
985985

986+
### WeakMap 的语法
987+
988+
WeakMap 与 Map 在 API 上的区别主要是两个,一是没有遍历操作(即没有`key()``values()``entries()`方法),也没有`size`属性。因为没有办法列出所有键名,某个键名是否存在完全不可预测,跟垃圾回收机制是否运行相关。这一刻可以取到键名,下一刻垃圾回收机制突然运行了,这个键名就没了,为了防止出现不确定性,就统一规定不能取到键名。二是无法清空,即不支持`clear`方法。因此,`WeakMap`只有四个方法可用:`get()``set()``has()``delete()`
989+
990+
```javascript
991+
const wm = new WeakMap();
992+
993+
// size、forEach、clear 方法都不存在
994+
wm.size // undefined
995+
wm.forEach // undefined
996+
wm.clear // undefined
997+
```
998+
986999
### WeakMap 的示例
9871000

9881001
WeakMap 的例子很难演示,因为无法观察它里面的引用会自动消失。此时,其他引用都解除了,已经没有引用指向 WeakMap 的键名了,导致无法证实那个键名是不是存在。
@@ -1014,32 +1027,37 @@ undefined
10141027
> let wm = new WeakMap();
10151028
undefined
10161029

1030+
// 新建一个变量 key,指向一个 5*1024*1024 的数组
10171031
> let key = new Array(5*1024*1024);
10181032
undefined
10191033

1034+
// 设置 WeakMap 实例的键名,也指向 key 数组
1035+
// 这时,key 数组的引用计数为 2,
1036+
// 变量 key 引用一次,WeakMap 的键名引用第二次
10201037
> wm.set(key,1);
10211038
WeakMap {}
10221039

10231040
> global.gc();
10241041
undefined
10251042

1026-
// 可以看到,增加数组key之后,heapUsed增加到45M了;
1043+
// 这时内存占用 heapUsed 增加到 45M 了
10271044
> process.memoryUsage();
10281045
{ rss: 67538944,
10291046
heapTotal: 7376896,
10301047
heapUsed: 45782816,
10311048
external: 8945 }
10321049

1033-
// 清除外界对key的引用,但没有手动清除WeakMap对key的引用
1050+
// 清除变量 key 对数组的引用,
1051+
// 但没有手动清除 WeakMap 实例的键名对数组的引用
10341052
> key = null;
10351053
null
10361054

10371055
// 再次执行垃圾回收
10381056
> global.gc();
10391057
undefined
10401058

1041-
// heapUsed 4M左右
1042-
// 可以看到WeakMap对key的引用没有阻止gc对key所占内存的回收;
1059+
// 内存占用 heapUsed 变回 4M 左右
1060+
// 可以看到 WeakMap 的键名引用没有阻止 gc 对内存的回收
10431061
> process.memoryUsage();
10441062
{ rss: 20639744,
10451063
heapTotal: 8425472,
@@ -1049,19 +1067,6 @@ undefined
10491067

10501068
上面代码中,只要外部的引用消失,WeakMap 内部的引用,就会自动被垃圾回收清除。由此可见,有了 WeakMap 的帮助,解决内存泄漏就会简单很多。
10511069

1052-
### WeakMap 的语法
1053-
1054-
WeakMap 与 Map 在 API 上的区别主要是两个,一是没有遍历操作(即没有`key()``values()``entries()`方法),也没有`size`属性。因为没有办法列出所有键名,这个键名是否存在完全不可预测,跟垃圾回收机制是否运行相关。二是无法清空,即不支持`clear`方法。因此,`WeakMap`只有四个方法可用:`get()``set()``has()``delete()`
1055-
1056-
```javascript
1057-
const wm = new WeakMap();
1058-
1059-
// size、forEach、clear 方法都不存在
1060-
wm.size // undefined
1061-
wm.forEach // undefined
1062-
wm.clear // undefined
1063-
```
1064-
10651070
### WeakMap 的用途
10661071

10671072
前文说过,WeakMap 应用的典型场合就是 DOM 节点作为键名。下面是一个例子。

0 commit comments

Comments
 (0)