JavaScript 弱引用和强引用底层示例详解
什么是引用
在 JavaScript 中,引用是指对内存中存储的对象的指针。当创建一个对象时,JavaScript 会为其在内存中分配一块区域,并返回一个引用,用于在程序执行时访问该对象。在 JavaScript 中,所有变量都是通过引用来存储和访问的,因此引用是非常重要的概念。
弱引用和强引用
在 JavaScript 中,为了确保内存不会被无限占用,需要自动清理不再使用的对象。这就需要对引用的类型进行区分,通常可以分为弱引用和强引用。
弱引用
弱引用是指当对象所持有的所有强引用都被释放后,该对象就会被自动回收。所以弱引用通常用于缓存、垃圾回收和对象绑定等场景。
在 JavaScript 中,可以通过以下两种方式来创建弱引用:
WeakMap
WeakMap 是 JavaScript 中的一个特殊对象,用于存储键值对。WeakMap 和 Map 类似,当键值对的键被释放时,值也会被自动删除。
以下是使用 WeakMap 创建弱引用的示例:
const wm = new WeakMap()
const obj1 = {}
const obj2 = {}
wm.set(obj1, 'hello')
wm.set(obj2, 'world')
console.log(wm.get(obj1)) // 'hello'
console.log(wm.get(obj2)) // 'world'
obj1 = null
console.log(wm.get(obj1)) // undefined
WeakSet
WeakSet 是 JavaScript 中用于存储一组值的集合,它们可以是任意类型的值。当一个值被释放时,它会被自动从集合中删除。
以下是使用 WeakSet 创建弱引用的示例:
const ws = new WeakSet()
const obj1 = {}
const obj2 = {}
ws.add(obj1)
ws.add(obj2)
console.log(ws.has(obj1)) // true
console.log(ws.has(obj2)) // true
obj1 = null
console.log(ws.has(obj1)) // false
强引用
强引用是指当对象被一个或多个强引用所引用时,该对象会一直存在于内存中,不会被自动回收。
在 JavaScript 中,常用的为强引用的场景是:对象作为一个方法的参数或返回值传递时,或者对象绑定到了全局变量上。
以下是使用常规方式创建强引用的示例:
const obj1 = {}
const obj2 = {}
const obj3 = obj1
console.log(obj1 === obj3) // true
obj3 = obj2
console.log(obj1 === obj3) // false
示例
以下为2个示例分别使用了弱引用和强引用:
示例1:WeakMap 实现缓存
WeakMap 可以非常方便地实现缓存功能,当缓存中的对象不再被引用时,就会自动清理。
class Cache {
constructor() {
this._cache = new WeakMap()
}
getItem(key) {
return this._cache.get(key)
}
setItem(key, value) {
this._cache.set(key, value)
}
deleteItem(key) {
this._cache.delete(key)
}
}
const cache = new Cache()
const obj = {}
cache.setItem(obj, 'hello')
console.log(cache.getItem(obj)) // 'hello'
obj = null
console.log(cache.getItem(obj)) // undefined
示例2:强引用绑定全局变量
强引用通常用于保持对象的生命周期和可访问性。
// 将对象绑定到全局变量上
const obj = {}
window.obj = obj
// 从全局变量中删除对象
delete window.obj
// 观察对象是否被回收
let count = 0
const interval = setInterval(() => {
if (count > 10) {
clearInterval(interval)
console.log('清理完成')
} else {
console.log('对象已释放' + (window.obj === undefined))
count++
}
}, 500)
在以上示例中,我们将一个对象绑定到了全局变量 window 上,并通过 delete 运算符删除该对象。然后,通过 setInterval 方法,在短时间内进行多次判断,以观察该对象的生命周期。
总结
弱引用和强引用都是 JavaScript 中的重要概念,它们可以帮助我们更好地控制内存的使用和回收。在实际编程中,需要根据具体情况灵活选择不同类型的引用,以适应不同的需求和场景。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript 弱引用强引用底层示例详解 - Python技术站