最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 《javascript高级程序设计》学习笔记 | 6.5.WeakMap

    正文概述 掘金(simon9124)   2021-04-08   417

    WeakMap

    • WeakMap 是 ECMAScript6 的新增特性,是一种新的集合类型,是 Map 的“兄弟”类型,也是 Map 的子集

    • “weak” 描述的是 JS 垃圾回收程序对待“弱映射”中键的方式

      相关代码 →

    基本 API

    • 使用new 关键字WeakMap 构造函数可以创建一个空的弱映射
    const wm = new WeakMap()
    console.log(wm) // WeakMap {}
    
    • 若映射的只能是Object或者继承自 Object 的类型(非对象设置键会报错),值的类型无限制
    // 使用嵌套数组初始化若映射
    const key1 = { id: 1 },
      key2 = { id: 2 },
      key3 = { id: 3 }
    
    const wm1 = new WeakMap([
      [key1, 'val1'],
      [key2, 'val2'],
      [key3, 'val3'],
    ])
    console.log(wm1.get(key1)) // 'val1'
    console.log(wm1.get(key2)) // 'val2'
    console.log(wm1.get(key3)) // 'val3'
    
    // 只要有一个键无效就会抛出错误,导致初始化失败
    const wm2 = new WeakMap([
      [key1, 'val1'],
      [key2, 'val2'],
      [key3, 'val3'],
      ['key4', 'val4'], // TypeError: Invalid value used as weak map key
    ])
    
    • 可以将原始值包装成对象再用作键
    const key4 = new String('key4')
    const wm3 = new WeakMap([
      [key1, 'val1'],
      [key2, 'val2'],
      [key3, 'val3'],
      [key4, 'val4'],
    ])
    console.log(wm3.get(key4)) // 'val4'
    
    • 初始化后,可以使用set()添加键/值对,使用get()has()进行查询,使用delete()删除值(同 Map ,但 WeakMap 没有 clear()方法,也没有自带的 size 属性)
    const wm4 = new WeakMap()
    console.log(wm4.size) // undefined,WeakMap不自带size属性
    
    const key5 = { id: 1 },
      key6 = { id: 2 }
    
    wm4.set(key5, 'Matt').set(key6, 'Frisbie')
    console.log(wm4.has(key5)) // true
    console.log(wm4.get(key5)) // 'Matt'
    
    wm4.delete(key5) // 删除这个键值对
    console.log(wm4.has(key5)) // false
    console.log(wm4.get(key5)) // undefined
    console.log(wm4.has(key6)) // true
    
    // wm4.clear() // TypeError: wm4.clear is not a function,WeakMap没有clear方法
    
    • set()方法返回弱映射实例,因此可以把多个操作连缀起来,从初始化到添加键/值对(同 Map)
    const wm5 = new WeakMap().set(key5, 'Matt')
    console.log(wm5) // WeakMap { { id: 1 } => 'Matt' }
    

    弱键

    • 弱映射的不属于正式的引用,不会阻止垃圾回收
    • 只要键存在键/值就存在于映射中,并被当作对值的引用,不会被垃圾回收
    const wm6 = new WeakMap()
    wm6.set({}, 'val') // 初始化一个新对象作为建,没有指向这个对象的其他引用,代码执行后键和值均会被当作垃圾回收
    
    const wm7 = new WeakMap()
    const container = { key: {} } // container对象维护着wm7中键的引用
    wm7.set(container.key, 'val') // 键和值均不会成为垃圾回收的目标
    container.key = null // 切断键对象的引用,键和值才会被垃圾回收
    

    不可迭代键

    • 弱映射中的键值对在任何时候都能被销毁,因此没有迭代键值对的方法
    • 弱映射之所以只能用对象作为键是为了保证只有通过键对象的引用才能取得值

    使用弱映射

    私有变量

    • 私有变量会储存在弱映射中,以对象实例,以私有成员的字典
    • 闭包把 WeakMap 包起来,让弱映射与外界完全隔离开,实现闭包私有变量模式
    const UserClosure = (() => {
      // 用闭包把WeakMap包起来
      const wm9 = new WeakMap()
    
      class User {
        constructor(id) {
          this.idProperty = Symbol('id') // 创建符号
          this.setId(id)
        }
        setId(id) {
          this.setPrivate(this.idProperty, id)
        }
        setPrivate(property, value) {
          const privateMembers = wm9.get(this) || {}
          privateMembers[property] = value // { idProperty: Symbol(id): id }
          wm9.set(this, privateMembers)
        }
        getId() {
          return this.getPrivate(this.idProperty)
        }
        getPrivate(property) {
          return wm9.get(this)[property] // 获取到id
        }
      }
      return User
    })()
    const user2 = new UserClosure(123)
    console.log(user2) // User { idProperty: Symbol(id) }
    console.log(user2.getId()) // 123
    
    user.setId(456)
    console.log(user.getId()) // 456
    
    // console.log(wm9) // ReferenceError: wm9 is not defined,拿不到弱映射,无法获取弱映射中对应的值,成功设置私有变量
    

    DOM 节点元数据

    • WeakMap 实例不会妨碍垃圾回收,因此非常适合保存关联元数据
    // 给节点关联元数据,保存在映射中
    const m = new Map()
    const loginButton = document.querySelector('#login')
    m.set(loginButton, { disabled: true }) // 即使DOM被删除映射仍然存在
    
    // 给节点关联元数据,保存在弱映射中
    const wm10 = new WeakMap()
    const loginButtin2 = document.querySelector('#login')
    wm10.set(loginButton, { disabled: true }) // DOM被删除(若没有其他地方引用loginButton)弱映射被回收
    

    总结 & 问点

    • WeakMap 属于什么类型?如何创建 WeakMap 类型?初始化后可以对其进行哪些操作?
    • WeakMap 的键有什么限制?如果想使用原始值作为建,需要怎样的操作?
    • WeakMap 的垃圾回收机制是什么?为什么说 WeakMap 适合保存关联元数据?
    • 写一段代码,用弱映射实现设置私有变量

    起源地下载网 » 《javascript高级程序设计》学习笔记 | 6.5.WeakMap

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元