JS中的WeakMap与WeakSet
JS WeakMap WeakSet
2023-06-13 09:13:55 时间
源码
前往Github获取本文源码。
介绍
WeakMap
与WeakSet
都是一种优化使用内存的解决方案。这两个数据结构的引用不会导致这些对象不被回收。上来就说这些有点太枯燥了,还是先聊聊它们能干什么。
WeakSet
集合就是一堆互异的数据,想必这个读者都早就明白了,这里不多说。
相对于正统Set
,WeakSet
只提供三个方法:add
、delete
和has
。正如前文所说,它们的引用GC是不管的,所以它也不清楚自己到底引用了多少个对象,故只能判断这个对象存在与否,和增删对象。
说了这么多,还是来点代码:
const set = new WeakSet()
let mike = { name: 'Mike', age: 17 }
let john = { name: 'John', age: 18 }
set.add(john).add(mike)
john = undefined
当运行完这段代码的时候,john
已经不再引用原来的对象,此时存放于set
中的原john
对象就可以被删掉了。但是到底删不删还是由JS引擎说得算的。
既然它对于对象都是弱引用,那么它就不能添加一个不是对象的基本类型。
set.add(1)
// TypeError: Invalid value used in weak set
WeakMap
上文提到的WeakSet
,我是不知道它到底被广泛应用到哪里了。但是WeakMap
有一个特别有用的地方:存储私有变量。
我们知道,JS中没有真正的私有,但是我在使用TS编译器就运用了WeakMap
来储存所谓的私有变量。这里演示一下其原理,因为TS编译后的代码不是人看的:
const barStorage = new WeakMap()
class Foo {
constructor(bar) {
barStorage.set(this, bar)
}
get bar() {
return barStorage.get(this)
}
set bar(_) {
throw new Error('cannot set private member!')
}
}
const foo1 = new Foo(2)
const foo2 = new Foo(3)
console.log(foo1.bar, foo2.bar)
// 2 3
foo1.bar = 21
// Error: cannot set private member!
由于WeakMap
对对象的引用不会被GC当回事,所以当我们foo1
或foo2
使用完毕被回收后,它们在WeakMap
里的引用也会被清除掉,这样就节约了内存。
顺带一提,同WeakSet
一样,WeakMap
的键必须是对象:
barStorage.set(1, 2)
// TypeError: Invalid value used as weak map key
这样就保证了当作为键的对象被回收后,它存的值也会被回收。
相关文章
- js书写原生ajax,JS 原生ajax写法
- js面试题及答案2020_JS面试题大全
- 个人总结 – JS逆向解析[通俗易懂]
- JS面试题-js新增基本数据类型BigInt
- js定时器与延时器_JS做定时器倒计时
- Js生成二维码_js在线生成二维码
- Node.js是什么?能做什么?终于有人讲明白了
- 用SQL Server和JS实现数据库管理技术(sqlserver.js)
- JS技术连接Oracle数据库实现数据交互(js连接oracle实例)
- JS在Oracle中的应用(js如何oracle)
- JavaScript探索之旅掌握Oracle和JS的完美融合(js与oracle)
- Oracle中JS的优势让数据库性能提升(oracle中 js)
- 使用Oracle和JS开发新一代应用仿真世界(oracle js)
- JS实现php的伪分页
- js发个判断字符串是否为符合标准的函数
- JS输入字数判断实现代码
- 纯js实现背景图片切换效果代码
- JS模块与命名空间的介绍
- js弹出层(jQuery插件形式附带reLoad功能)
- js捕获鼠标滚轮事件代码
- js数组循环遍历数组内所有元素的方法
- js二维数组定义和初始化的三种方法总结
- js判断游览器类型及版本号的代码
- js父页面与子页面不同时显示的方法