数据存储
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)
WeakMap
和Map不同,WeakMap的键只能是引用数据类型,不能是基本数据类型,而且设置键时不会形成一次地址引用,也就是不会计数增加1,当堆内存中的数据没有了引用时,改键也会被回收,只是回收的时机我们不知道,但是我们可以通过定时器打印该值。
let wmap = new WeakMap()
let obj = {name:'ibanez'}
wmap.set(obj,'guitar')
obj = null
setTimeout(()=>{
console.log(wmap)
},10000)
同时,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