KFCVme50-CrazyThursday / sheng-study

个人学习总结与代码知识点
1 stars 0 forks source link

18、WeakMap 类和 WeakSet 类 #18

Open KFCVme50-CrazyThursday opened 4 years ago

KFCVme50-CrazyThursday commented 4 years ago

早晨来到公司,翻了下微信群,看到小夕姐推送了一篇文章 你不知道的WeakMap ,翻看了下。想到了在 js版数据结构与算法 那本书中也提到了,就想着查阅下整理一下。

KFCVme50-CrazyThursday commented 4 years ago

以下来源js版数据结构与算法第三版本:

除了 Set 和 Map 这两种新的数据结构,ES2015 还增加了它们的弱化版本,WeakSet 和 WeakMap。 基本上,Map 和 Set 与其弱化版本之间仅有的区别是:

 WeakSet 或 WeakMap 类没有 entries、keys 和 values 等方法;  只能用对象作为键。

创建和使用这两个类主要是为了性能。WeakSet 和 WeakMap 是弱化的(用对象作为键), 没有强引用的键。这使得 JavaScript 的垃圾回收器可以从中清除整个入口。

另一个优点是,必须用键才可以取出值。这些类没有 entries、keys 和 values 等迭代器方法,因此,除非你知道键,否则没有办法取出值。这印证了我们在第 4 章的做法,即使用 WeakMap类封装 ES2015 类的私有属性。

使用 WeakMap 类的例子如下。

    const map = new WeakMap();

    const ob1 = { name: 'Gandalf' }; // {1}
    const ob2 = { name: 'John' };
    const ob3 = { name: 'Tyrion' };

    map.set(ob1, 'gandalf@email.com'); // {2}
    map.set(ob2, 'johnsnow@email.com'); 
    map.set(ob3, 'tyrion@email.com');

    console.log(map.has(ob1)); // true {3} 
    console.log(map.get(ob3)); // tyrion@email.com {4} 
    map.delete(ob2); // {5}
    WeakMap 类也可以用 set 方法(行{2}),但不能使用数、字符串、布尔值等基本数据类型, 需要将名字转换为对象(行{1})。

    搜索(行{3})、读取(行{4})和删除值(行{5}),也要传入作为键的对象。 

    同样的逻辑也适用于 WeakSet 类。
KFCVme50-CrazyThursday commented 4 years ago

未完

KFCVme50-CrazyThursday commented 4 years ago

from 现代JavaScript教程

1、通常,当对象、数组这类数据结构在内存中时,它们的子元素,如对象的属性、数组的元素都是可以访问的。 例如,如果把一个对象放入到数组中,那么只要这个数组存在,那么这个对象也就存在,即使没有其他对该对象的引用。

就像这样:

let john = { name: "John" };
let array = [ john ];
john = null; // 覆盖引用
// john 被存储在数组里, 所以它不会被垃圾回收机制回收
// 我们可以通过 array[0] 来获取它

2、类似的,如果我们使用对象作为常规 Map 的键,那么当 Map 存在时,该对象也将存在。它会占用内存,并且应该不会被(垃圾回收机制)回收。

let john = { name: "John" };
let map = new Map();
map.set(john, "...");
john = null; // 覆盖引用

// john 被存储在 map 中,
// 我们可以使用 map.keys() 来获取它

类似的,如果我们使用对象作为常规 Map 的键,那么当 Map 存在时,该对象也将存在。它会占用内存,并且应该不会被(垃圾回收机制)回收。

例如:

let john = { name: "John" };
let map = new Map();
map.set(john, "...");
john = null; // 覆盖引用
// john 被存储在 map 中,
// 我们可以使用 map.keys() 来获取它
KFCVme50-CrazyThursday commented 4 years ago

image