【javascript】 ES6 中的 Map,weakMap,Set,weakSet

95 阅读2分钟

数据存储

javascript中引用数据类型的存储分为栈内存和堆内存,栈内存中保存的是对应堆内存中数据的地址,下面堆内存中的数据被引用了两次。

    let a = {name:'ibanez'}
    let b = a
    a = null
    console.log(a) //输出:null
    console.log(b) 输出:{name:'ibanez'}

声明一个a变量存储对象的地址,然后把改地址复制一份赋值给b,这样a,b同时指向堆内存中的数据。a变为null,也就是断开了连接,但是b的指向依然存在。

引用计数

引用计数属于浏览器的垃圾回收机制中的一种。浏览器会记住一个变量被引用了多少次,如果引用次数变为0,就变成【不可达】状态,浏览器就会在合适的时机释放数据占据的堆内存,只是这个时机是不可预测的。

    let a = {name:'ibanez'}
    let b = a //计数 +1
    let c = a 计数 +1
    a = null //计数 -1
    b = null //计数 -1
    c = null //计数 -1 变为0,

Map WeakMap

ES6中的Map类似普通对象{},也是采用键值对的方式存储数据,只是Map可以设置键为对象,数据,函数,普通对象则不行。

    let map = new Map()
    let obj = {info:'guitar'}
    //设置值
    map.set(1,'1')
    map.set('name','ibanez')
    map.set(obj,'guitar')
    // 取值
    map.get(obj) // 'guitar'
    // 取个数
    map.size // 3
    //遍历
    map.forEach((item)=>{console.log(item)}) // 1,'ibanez','guitar'
    ```//删除
    map.delete(1)
    //删除全部
    map.clear()
    //判断是否存在某个值
    map.has(1) //true

Map

在Map中,把一个引用数据类型设置为键,相当复制了一份引用地址,对该变量的引用增加1。从下面代码看出,Map的键对该对象的引用一直存在。

        let map = new Map()
        let obj = {name:'ibanez'}
        map.set(obj,'guitar')
        obj = null
        console.log(map)

ade38bded1662b23f6f74cebf557311.png

WeakMap

和Map不同,WeakMap的键只能是引用数据类型,不能是基本数据类型,而且设置键时不会形成一次地址引用,也就是不会计数增加1,当堆内存中的数据没有了引用时,改键也会被回收,只是回收的时机我们不知道,但是我们可以通过定时器打印该值。

    let wmap = new WeakMap()
    let obj = {name:'ibanez'}
    wmap.set(obj,'guitar')
    obj = null
    setTimeout(()=>{
        console.log(wmap)
    },10000)

92bbab804886bee743efe60c3639488.png

同时,Map属性的size,forEach,clear都不能使用。

Set WeakSet

Set类似于传统的数据存储数据的方式,同样,WeakSet也是只能存储引用数据类型的值,否则会报错。WeakSet的值回收就如同Map,属于弱引用,不多赘述。

    let set = new Set()
    //传值
    set.add('1')
    set.add({name:'xm'})
    //长度
    set.size //2
    //判断是否含有某个值
    set.has('1')
    //遍历
    set.forEach((item)=>{console.log(item)}) // '1' {name:'xm'}
    //删除单个值
    set.delete('1')
    //删除所有
    set.clear()
    
    
    let wset = new WeakSet()
    wset.add(1) //报错 Invalid value used in weak set