LeeeeeeM / blog

daily blog
0 stars 0 forks source link

Map && WeakMap使用 #4

Open LeeeeeeM opened 6 years ago

LeeeeeeM commented 6 years ago

最近在研究快应用的style节点,发现我们的框架有很多对对象的引用,当页面销毁的时候,仍然会有很多的StyleNode节点仍然会保持对多个抽象对象引用。每次执行destroy的时候需要手动的进行null指向或者用性能极差的delete操作。到底有没有什么解决的方法? 众所周知,v8有自己的GC,闭包会阻止GC,手动将对象指向null或者undefined也可以进行垃圾回收(可以使用profiler自己做个试验;debugger可以看到closure被保存在scope内部,不会被GC)。

var obj = {
    name: 'mi',
    age: 30
}
obj = null
LeeeeeeM commented 6 years ago

好了,首先我们要知道,js原始对象的key值只能是字符串string类型。

var b = {
    name: 'mi'
}
var a = {}
a[b] = 123
// {[object Object]: 123}

不管你的对象多复杂,始终要调用toString方法转化为字符串。所以想用对象作为key值在以前是没法实现的。直到后来引入了Map和Set。

var c = Symbol.for('mi')
var user = {
    name: 'mi',
    age: 30
}
var m = new Map()
m.set('name', 'mi')
m.set(c, 123)
m.set(user, 'mi')
// Map(3) {"name" => "mi", Symbol(mi) => 123, {…} => "mi"}
LeeeeeeM commented 6 years ago

这里看到新的数据结构可以用Object作为key。 但是,问题又来了,假设我作为key的对象被有意无意删除,那么我的value是无论如何都无法再获取的。

var c = Symbol.for('mi')
var user = {
    name: 'mi',
    age: 30
}
var m = new Map()
m.set('name', 'mi')
m.set(c, 123)
m.set(user, 'mi')
user = null
m.get(user)
// undefined   Map(3) {"name" => "mi", Symbol(mi) => 123, {…} => "mi"}

懵逼!明明获取不到user,然后Map实例里面依然保存对象。假设通过构造函数大量构造地对象,之后又做了批量操作,内存有大量的垃圾对象被引用而无法被GC掉,怎么办??

LeeeeeeM commented 6 years ago

的确是个问题,所以ES6在引入Map的同时又引入了WeakMap。 https://github.com/ruanyf/es6tutorial/issues/362 后面不说了,自己看评论吧