Set、Map、WeakSet 、WeakMap

2019-02-19  本文已影响0人  LenHong

1. Set

Set 本身是一种构造函数,用来生成 Set 数据结构(类似于数组,但成员是唯一且无序的,没有重复的值)。

const s = new Set()
[1, 2, 3, 4, 3, 2, 1].forEach(x => s.add(x))

for (let i of s) {
    console.log(i)  // 1 2 3 4
}

//Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5

利用Set的特性来实现数组的去重

// 去除数组的重复成员
[...new Set(array)]

也可以用于去除字符串里面的重复字符

[...new Set('ababbc')].join('')
// "abc"

Array.from方法可以将 Set 结构转为数组。

const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);

使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}

// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

Set 结构的实例有以下属性。

Set 实例的方法分为两大类:

  1. 操作方法(用于操作数据)
    add(value):添加某个值,返回 Set 结构本身。
    delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
    has(value):返回一个布尔值,表示该值是否为Set的成员。
    clear():清除所有成员,没有返回值。

  2. 遍历方法(用于遍历成员)
    keys():返回键名的遍历器
    values():返回键值的遍历器
    entries():返回键值对的遍历器
    forEach():使用回调函数遍历每个成员

注意:Set 结构的键名就是键值(两者是同一个值)

2. WeakSet

3. Map

ES6 提供了 Map 数据结构。类似于对象,也是键值对的集合,但是Map的“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。

Map 可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

const map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);

map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author"

Map 结构的实例有 size属性:返回实例的成员总数。

  1. Map 实例的操作方法:
    set(key, value):set方法设置键名key对应的键值为value,然后返回整个 Map 结构
    get(key):get方法读取key对应的键值,如果找不到key,返回undefined。
    delete(key):删除某个值,返回一个布尔值,表示删除是否成功。
    has(key):返回一个布尔值,表示该值是否为Map 的成员。
    clear():清除所有成员,没有返回值。

  2. 遍历方法
    keys():返回键名的遍历器。
    values():返回键值的遍历器。
    entries():返回所有成员的遍历器。
    forEach():遍历 Map 的所有成员。

4. WeakMap

const e1 = document.getElementById('foo');
const e2 = document.getElementById('bar');
const arr = [
  [e1, 'foo 元素'],
  [e2, 'bar 元素'],
];

上面代码中,e1和e2是两个对象,我们通过arr数组对这两个对象添加一些文字说明。这就形成了arr对e1和e2的引用,一旦不再需要这两个对象,我们就必须手动删除这个引用,否则垃圾回收机制就不会释放e1和e2占用的内存。

// 不需要 e1 和 e2 的时候
// 必须手动删除引用
arr [0] = null;
arr [1] = null;

上面这样的写法显然很不方便。一旦忘了写,就会造成内存泄露。

WeakMap 就是为了解决这个问题而诞生的,它的键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。

基本上,如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap。一个典型应用场景是,在网页的 DOM 元素上添加数据,就可以使用WeakMap结构。当该 DOM 元素被清除,其所对应的WeakMap记录就会自动被移除。

注意,WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。

总结

上一篇 下一篇

猜你喜欢

热点阅读