1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00

docs(set): edit WeakMap

This commit is contained in:
ruanyf 2017-06-28 21:41:08 +08:00
parent 88930c14a2
commit 4de0cd6b50

View File

@ -983,6 +983,19 @@ wm.get(key)
上面代码中,键值`obj`是正常引用。所以,即使在 WeakMap 外部消除了`obj`的引用WeakMap 内部的引用依然存在。 上面代码中,键值`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 的例子很难演示,因为无法观察它里面的引用会自动消失。此时,其他引用都解除了,已经没有引用指向 WeakMap 的键名了,导致无法证实那个键名是不是存在。 WeakMap 的例子很难演示,因为无法观察它里面的引用会自动消失。此时,其他引用都解除了,已经没有引用指向 WeakMap 的键名了,导致无法证实那个键名是不是存在。
@ -1014,23 +1027,28 @@ undefined
> let wm = new WeakMap(); > let wm = new WeakMap();
undefined undefined
// 新建一个变量 key指向一个 5*1024*1024 的数组
> let key = new Array(5*1024*1024); > let key = new Array(5*1024*1024);
undefined undefined
// 设置 WeakMap 实例的键名,也指向 key 数组
// 这时key 数组的引用计数为 2
// 变量 key 引用一次WeakMap 的键名引用第二次
> wm.set(key,1); > wm.set(key,1);
WeakMap {} WeakMap {}
> global.gc(); > global.gc();
undefined undefined
// 可以看到增加数组key之后heapUsed增加到45M了 // 这时内存占用 heapUsed 增加到 45M 了
> process.memoryUsage(); > process.memoryUsage();
{ rss: 67538944, { rss: 67538944,
heapTotal: 7376896, heapTotal: 7376896,
heapUsed: 45782816, heapUsed: 45782816,
external: 8945 } external: 8945 }
// 清除外界对key的引用但没有手动清除WeakMap对key的引用 // 清除变量 key 对数组的引用,
// 但没有手动清除 WeakMap 实例的键名对数组的引用
> key = null; > key = null;
null null
@ -1038,8 +1056,8 @@ null
> global.gc(); > global.gc();
undefined undefined
// heapUsed 4M左右 // 内存占用 heapUsed 变回 4M 左右,
// 可以看到WeakMap对key的引用没有阻止gc对key所占内存的回收 // 可以看到 WeakMap 的键名引用没有阻止 gc 对内存的回收
> process.memoryUsage(); > process.memoryUsage();
{ rss: 20639744, { rss: 20639744,
heapTotal: 8425472, heapTotal: 8425472,
@ -1049,19 +1067,6 @@ undefined
上面代码中只要外部的引用消失WeakMap 内部的引用,就会自动被垃圾回收清除。由此可见,有了 WeakMap 的帮助,解决内存泄漏就会简单很多。 上面代码中只要外部的引用消失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 的用途
前文说过WeakMap 应用的典型场合就是 DOM 节点作为键名。下面是一个例子。 前文说过WeakMap 应用的典型场合就是 DOM 节点作为键名。下面是一个例子。