From 4de0cd6b50e3c2113617242fc323bf39eb2be4e2 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 28 Jun 2017 21:41:08 +0800 Subject: [PATCH] docs(set): edit WeakMap --- docs/set-map.md | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/docs/set-map.md b/docs/set-map.md index 0b38f21..29f4157 100644 --- a/docs/set-map.md +++ b/docs/set-map.md @@ -983,6 +983,19 @@ wm.get(key) 上面代码中,键值`obj`是正常引用。所以,即使在 WeakMap 外部消除了`obj`的引用,WeakMap 内部的引用依然存在。 +### WeakMap 的语法 + +WeakMap 与 Map 在 API 上的区别主要是两个,一是没有遍历操作(即没有`key()`、`values()`和`entries()`方法),也没有`size`属性。因为没有办法列出所有键名,某个键名是否存在完全不可预测,跟垃圾回收机制是否运行相关。这一刻可以取到键名,下一刻垃圾回收机制突然运行了,这个键名就没了,为了防止出现不确定性,就统一规定不能取到键名。二是无法清空,即不支持`clear`方法。因此,`WeakMap`只有四个方法可用:`get()`、`set()`、`has()`、`delete()`。 + +```javascript +const wm = new WeakMap(); + +// size、forEach、clear 方法都不存在 +wm.size // undefined +wm.forEach // undefined +wm.clear // undefined +``` + ### WeakMap 的示例 WeakMap 的例子很难演示,因为无法观察它里面的引用会自动消失。此时,其他引用都解除了,已经没有引用指向 WeakMap 的键名了,导致无法证实那个键名是不是存在。 @@ -1014,23 +1027,28 @@ undefined > let wm = new WeakMap(); undefined +// 新建一个变量 key,指向一个 5*1024*1024 的数组 > let key = new Array(5*1024*1024); undefined +// 设置 WeakMap 实例的键名,也指向 key 数组 +// 这时,key 数组的引用计数为 2, +// 变量 key 引用一次,WeakMap 的键名引用第二次 > wm.set(key,1); WeakMap {} > global.gc(); undefined -// 可以看到,增加数组key之后,heapUsed增加到45M了; +// 这时内存占用 heapUsed 增加到 45M 了 > process.memoryUsage(); { rss: 67538944, heapTotal: 7376896, heapUsed: 45782816, external: 8945 } -// 清除外界对key的引用,但没有手动清除WeakMap对key的引用 +// 清除变量 key 对数组的引用, +// 但没有手动清除 WeakMap 实例的键名对数组的引用 > key = null; null @@ -1038,8 +1056,8 @@ null > global.gc(); undefined -// heapUsed 4M左右, -// 可以看到WeakMap对key的引用没有阻止gc对key所占内存的回收; +// 内存占用 heapUsed 变回 4M 左右, +// 可以看到 WeakMap 的键名引用没有阻止 gc 对内存的回收 > process.memoryUsage(); { rss: 20639744, heapTotal: 8425472, @@ -1049,19 +1067,6 @@ undefined 上面代码中,只要外部的引用消失,WeakMap 内部的引用,就会自动被垃圾回收清除。由此可见,有了 WeakMap 的帮助,解决内存泄漏就会简单很多。 -### WeakMap 的语法 - -WeakMap 与 Map 在 API 上的区别主要是两个,一是没有遍历操作(即没有`key()`、`values()`和`entries()`方法),也没有`size`属性。因为没有办法列出所有键名,这个键名是否存在完全不可预测,跟垃圾回收机制是否运行相关。二是无法清空,即不支持`clear`方法。因此,`WeakMap`只有四个方法可用:`get()`、`set()`、`has()`、`delete()`。 - -```javascript -const wm = new WeakMap(); - -// size、forEach、clear 方法都不存在 -wm.size // undefined -wm.forEach // undefined -wm.clear // undefined -``` - ### WeakMap 的用途 前文说过,WeakMap 应用的典型场合就是 DOM 节点作为键名。下面是一个例子。