如果Weak中的Map如何导致内存泄漏?

时间:2018-03-13 17:47:18

标签: javascript ecmascript-6

我从MDN web docs查看了javascript的Map和WeakMap文档。

但是在这个(Why WeakMap?)主题中,我没有得到第二点,即WeakMap如何防止内存泄漏而Map没有。

有人会用某种例子简要解释一下。

- 编辑 -

实际上我想知道WeakMap如何保存弱引用或如何实现它。

但现在我得到了这个答案并解释了here

2 个答案:

答案 0 :(得分:1)

您在链接的文章中解释了

  

相比之下,本土WeakMaps持有"弱"对关键对象的引用,   这意味着它们不会阻止垃圾收集   不会引用关键对象。

WeakMaps不直接引用键,因此当键的所有其他引用都用完时,键仍然可以被垃圾收集,因此没有内存泄漏

答案 1 :(得分:0)

考虑LinkedListTree的实施。您可能不希望将nextlastchildrenparent公开为属性,而是将其设置为检查静态WeakMap的属性访问器因为存在这种关系。这样,您的实现允许关系维持弱连接。

HTML元素是解释这一点的好方法。假设您部分实现了一个HTML元素:

const HTMLElement = (() => {
  const children = new WeakMap()

  class Node {
    constructor () {
      children.set(this, [])
    }

    get children () {
      return children.get(this)
    }

    appendChild (element) {
      children.get(this).push(element)
      return element
    }

    removeChild (element) {
      const elements = children.get(this)
      elements.splice(elements.indexOf(element), 1)
      return element
    }
  }

  return class HTMLElement extends Node {
    constructor (tag) {
      super()
      this.tagName = tag.toUpperCase()
    }

    toString () {
      return `<${this.tagName}>${children.get(this).join('')}</${this.tagName}>`
    }
  }
})()

{
  const p = new HTMLElement('p')

  p.appendChild(new HTMLElement('a'))
  p.appendChild(new HTMLElement('span'))

  console.log(`${p}`)
}
// a and span get GC'd when reference to p is lost
console.log(typeof p)

如果childrenMap,则在p的引用丢失时会出现内存泄漏,因为其他人在HTMLElement之后仍会有强引用仍然可以访问。