es6 javascript的WeakSet数据结构

WeakSet 结构与 Set 类似, 也是不重复的值的集合。 但是, 它与 Set 有两个区别。
首先, WeakSet 的成员只能是对象, 而不能是其他类型的值。

其次, WeakSet 中的对象都是弱引用, 即垃圾回收机制不考虑 WeakSet 对该对象的引用, 也就是说, 如果其他对象都不再引用该对象, 那么垃圾回收机制会自动回收该对象所占用的内存, 不考虑该对象还存在于 WeakSet 之中。 这个特点意味着, 无法引用 WeakSet 的成员, 因此 WeakSet 是不可遍历的。

var ws = new WeakSet();
ws.add(1)
// TypeError: Invalid value used in weak set
ws.add(Symbol())
// TypeError: invalid value used in weak set
上面代码试图向 WeakSet 添加一个数值和Symbol值, 结果报错, 因为 WeakSet 只能放置对象。
WeakSet 是一个构造函数, 可以使用new命令, 创建 WeakSet 数据结构。

var ws = new WeakSet();
作为构造函数, WeakSet 可以接受一个数组或类似数组的对象作为参数。( 实际上, 任何具有 iterable 接口的对象, 都可以作为 WeakSet 的参数。) 该数组的所有成员, 都会自动成为 WeakSet 实例对象的成员。

var a = [
	[1, 2],
	[3, 4]
];
var ws = new WeakSet(a);
上面代码中, a是一个数组, 它有两个成员, 也都是数组。 将a作为 WeakSet 构造函数的参数, a的成员会自动成为 WeakSet 的成员。
注意, 是a数组的成员成为 WeakSet 的成员, 而不是a数组本身。 这意味着, 数组的成员只能是对象。

var b = [3, 4];
var ws = new WeakSet(b);
// Uncaught TypeError: Invalid value used in weak set(…)
上面代码中, 数组b的成员不是对象, 加入 WeaKSet 就会报错。
WeakSet 结构有以下三个方法。
WeakSet.prototype.add(value): 向 WeakSet 实例添加一个新成员。
WeakSet.prototype.delete(value): 清除 WeakSet 实例的指定成员。
WeakSet.prototype.has(value): 返回一个布尔值, 表示某个值是否在 WeakSet 实例之中。
下面是一个例子。

var ws = new WeakSet();
var obj = {};
var foo = {};
ws.add(window);
ws.add(obj);
ws.has(window); // true
ws.has(foo); // false
ws.delete(window);
ws.has(window); // false
WeakSet 没有size属性, 没有办法遍历它的成员。
ws.size // undefined
ws.forEach // undefined
ws.forEach(function(item) {
		console.log('WeakSet has ' + item)
	})
// TypeError: undefined is not a function
上面代码试图获取size和forEach属性, 结果都不能成功。
WeakSet 不能遍历, 是因为成员都是弱引用, 随时可能消失, 遍历机制无法保证成员的存在, 很可能刚刚遍历结束, 成员就取不到了。 WeakSet 的一个用处, 是储存 DOM 节点, 而不用担心这些节点从文档移除时, 会引发内存泄漏。
下面是 WeakSet 的另一个例子。

const foos = new WeakSet()
class Foo {
	constructor() {
		foos.add(this)
	}
	method() {
		if(!foos.has(this)) {
			throw new TypeError('Foo.prototype.method  只能在 Foo 的实例上调用! ');
		}
	}
}
上面代码保证了Foo的实例方法, 只能在Foo的实例上调用。 这里使用 WeakSet 的好处是, foos对实例的引用, 不会被计入内存回收机制, 所以删除实例的时候, 不用考虑foos, 也不会出现内存泄漏。







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值