WeakRef和FinalizationRegistry提供弱引用与对象回收后回调机制,用于避免内存泄漏。①WeakRef创建对对象的弱引用,仅在对象未被回收时通过deref()访问;②FinalizationRegistry在对象被回收后执行清理逻辑,传入注册时的附加数据;二者均不保证执行时机与顺序,适用于缓存等高级场景,但不可依赖其进行关键资源清理或解决循环引用问题。

JavaScript中的WeakRef和FinalizationRegistry为开发者提供了更灵活的内存管理方式,尤其适用于需要避免内存泄漏又不想强引用对象的场景。
WeakRef:弱引用对象
WeakRef允许你创建对一个对象的弱引用。这意味着只要没有其他强引用存在,垃圾回收器就可以在任何时候回收该对象,而不会因为WeakRef的存在而保留它。
使用WeakRef的基本方式如下:
const obj = { data: 'example' }; const weakRef = new WeakRef(obj); // 获取当前引用的对象(可能已被回收) const value = weakRef.deref(); if (value) { console.log(value.data); // 对象还存在 }注意:WeakRef不能用于原始值(如字符串、数字),只能用于对象。调用deref()方法返回对象本身,如果对象已被回收,则返回undefined。
立即学习“Java免费学习笔记(深入)”;
FinalizationRegistry:注册清理回调
FinalizationRegistry让你可以在对象被垃圾回收后执行一段清理逻辑。这适合用于释放外部资源、记录日志或调试内存使用情况。
创建一个终结器注册表并注册对象:
const registry = new FinalizationRegistry((heldValue) => { console.log('对象被回收,持有值为:', heldValue); }); const obj = { name: 'test' }; registry.register(obj, 'metadata-about-obj');当obj被回收时,回调函数会被调用,并传入注册时指定的“附加数据”(heldValue)。这个机制不保证立即执行,也不保证执行顺序,仅作为提示。
实际用途与注意事项
这两个特性主要用于高级场景,比如缓存、观察器模式或绑定原生资源。
- 不要依赖FinalizationRegistry做关键清理工作(如关闭文件句柄),因为它不保证执行时机甚至是否执行。
- WeakRef不应成为主要的数据结构依赖,频繁使用可能导致性能下降。
- 它们无法解决循环引用导致的内存泄漏,仍需合理设计对象生命周期。
基本上就这些。WeakRef和FinalizationRegistry提供了一种“尽力而为”的内存感知能力,让JS更贴近系统级资源管理的需求,但要谨慎使用,避免误用带来不可预测行为。










