弱引用:只要有對象引用,他就不會被垃圾回收。
介紹之前,不了解這些概念的同學(xué)可以參考一下以下鏈接。
WeakRefhttps://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakRef
WeakMap:weakMap.set(ref, realData)這邊針對的是對鍵的弱引用??梢岳斫鉃槭窍?qū)ο?ref 中添加值為 realData的內(nèi)容,通過ref來獲取realData,一旦不再持有對象的引用,即使你仍持有添加了該對象的 WeakMap 的引用對象,也會被垃圾回收。
WeakRef:允許您保留對另一個對象的弱引用,而不會阻止被弱引用對象被GC回收。-沒有很理解
看下面這個圖:

對WeakMap和WeakRef新的認(rèn)識:
WeakMap存的引用是個鍵,而這個鍵對里面內(nèi)容的引用是強引用的,key銷毀后才會弱化這個鍵里面的內(nèi)容。
WeakRef存的內(nèi)容直接是個弱引用的對象,引用的對象被銷毀了,ref.deref()返回的內(nèi)容自然也就為空了。被ref的內(nèi)容會被垃圾回收,但是不是立刻。
FinalizationGroup API可以注冊一個回調(diào),以便在垃圾回收器回收已注冊的對象時運行。可以手動寫一個回調(diào)函數(shù)用來做垃圾回收。
-
應(yīng)用
屬性私有-可以通過提供的方式來操作相應(yīng)的屬性,不能直接操作
數(shù)據(jù)緩存-想要用這些數(shù)據(jù),但是不想管理這些數(shù)據(jù)的生命周期
在 dom 對象上保存相關(guān)數(shù)據(jù)-當(dāng)dom移除的時候,刪除對相應(yīng)dom的引用
weakRef弱引用
用一段代碼來感受一下強引用和弱引用
//7、強引用
let map = new Map();
let key = new Array(5 * 1024 * 1024);
// 建立了 map 對 key 所引用對象的強引用
map.set(key, 1);
key = null;
// key = null 不會導(dǎo)致 key 的原引用對象被回收
console.log(key, map); //null Map(1) {Array(5242880) => 1}
//8、弱引用
let weakMap = new WeakMap();
let key1 = { map: 1 };
weakMap.set(key1, 1);
console.log(key1, weakMap.get(key1));//{map: 1} 1
key1 = null;
//可以發(fā)現(xiàn)key1被回收的時候,weakmap中的key1也被回收了
console.log(key1, weakMap.get(key1));//null undefined
//獲取內(nèi)存空間
//9、弱引用-應(yīng)用-將數(shù)據(jù)掛載到cache上,方式重復(fù)存入相同內(nèi)容,可以達到過濾的效果
let weakMap = new WeakMap();
function cache(data) {
console.log(weakMap.get(data));
if (!weakMap.get(data)) {
weakMap.set(data, data);
}
return weakMap.get(data);
}
let data = { a: 1, b: 2 };
let data1 = { a1: 1, b1: 2 };
let r1 = cache(data);
let r2 = cache(data1);
data.a = 2;
let r3 = cache(data);
console.log(r1, r2, r3, weakMap);
let weakmap = new WeakMap();
//將對象私有化
const privateData = new WeakMap();
class Person {
constructor(name, age) {
privateData.set(this, { name: name, age: age });
}
getName() {
return privateData.get(this).name;
}
getAge() {
return privateData.get(this).age;
}
}
let p = new Person("黃飄", 18);
let p2 = new Person("黃飄", 18);
//直接訪問屬性訪問不到,只能通過特定的方法去訪問
// console.log(p.age, p.name, p.getName(), privateData);
// console.log(p2.age, p2.name, p2.getName(), privateData);