弱引用之WeakMap和WeakRef

弱引用:只要有對象引用,他就不會被垃圾回收。
介紹之前,不了解這些概念的同學(xué)可以參考一下以下鏈接。

WeakMaphttps://es6.ruanyifeng.com/#docs/set-map

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回收。-沒有很理解

看下面這個圖:


image.png

對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);

參考文章:https://blog.csdn.net/howgod/article/details/103727351

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容