JavaScript 中 WeakMap 和 WeakSet 的实际使用场景是什么?

我最近在学习 JavaScript 的 WeakMap 和 WeakSet,了解到它们和 Map / Set 的主要区别是“弱引用”,不会阻止垃圾回收。

但是在实际开发中,我不太理解它们具体适合用在什么场景。

我目前的困惑主要有:

WeakMap 和 WeakSet 主要解决什么问题?
在什么情况下应该使用它们,而不是 Map / Set?
是否有一些常见的实际应用场景(比如缓存、DOM 相关操作等)?
它们在避免内存泄漏方面具体是如何起作用的?

如果可以的话,希望能提供一些简单、实际的代码示例帮助理解。

感谢解答!

我做过的尝试:
我已经查阅了一些资料,大致了解 WeakMapWeakSet 的特点,比如:

  • 它们的 key(或值)只能是对象
  • 是“弱引用”,不会阻止垃圾回收
  • 不支持遍历

另外我也自己写了一些简单的示例代码,比如用 MapWeakMap 分别存储对象,尝试观察它们在内存中的表现差异。

但是我在实际开发场景中还是不太清楚:

  • 在什么情况下必须使用 WeakMap / WeakSet
  • 它们相比 Map / Set 的实际优势体现在哪些具体场景中

我希望获得的帮助:
希望能了解一些更贴近实际开发的使用场景,例如:

  • 在什么情况下使用 WeakMap 可以有效避免内存泄漏
  • 是否有常见的业务案例(比如缓存、DOM 关联数据等)
  • 有没有一些典型的代码示例可以参考

感谢解答!