欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript?WeakMap的具體使用

 更新時(shí)間:2023年02月17日 09:29:02   作者:白瑕  
本文主要介紹了JavaScript?WeakMap的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

我在處理一個(gè)復(fù)雜對(duì)象的深拷貝方法時(shí)接觸到WeakMap, 其作為緩存結(jié)構(gòu)以解決對(duì)象內(nèi)部的循環(huán)引用問題. 為了改造這個(gè)方法, 決定研究WeakMap.

一、為何選用WeakMap

WeakMap和Map都可以使用對(duì)象作為鍵, Map也可以使用基本數(shù)據(jù)類型作為鍵, 在特殊的情況下(都使用對(duì)象作為鍵), 兩者看起來并無差別.

1. Map

Map會(huì)阻止JavaScript的內(nèi)存回收機(jī)制對(duì) 以一個(gè)已經(jīng)被回收的對(duì)象作為鍵的元素 進(jìn)行回收.
與Map內(nèi)存儲(chǔ)元素的方式有關(guān):

A map API could be implemented in JavaScript with two arrays (one for keys, one for values) shared by the four API methods.
`map`在JavaScript內(nèi)可通過使兩個(gè)數(shù)組被4種方法共享來實(shí)現(xiàn), 向`Map`內(nèi)設(shè)置元素時(shí)分別將鍵和值`push`進(jìn)這兩個(gè)數(shù)組.
Setting elements on this map would involve pushing a key and value onto the end of each of those arrays simultaneously.
訪問`Map`取值時(shí)需要遍歷, 從兩個(gè)數(shù)組內(nèi)找到匹配的值.

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
sayings.set('elephant', 'toot');
sayings.size; // 3
sayings.get('fox'); // undefined
sayings.has('bird'); // false
sayings.delete('dog');
sayings.has('dog'); // false

for (var [key, value] of sayings) {
? console.log(key + ' goes ' + value);
}
// "cat goes meow"
// "elephant goes toot"

sayings.clear();
sayings.size; // 0

首先Map內(nèi)部基于數(shù)組實(shí)現(xiàn), 取值賦值需要遍歷, 時(shí)間復(fù)雜度上來了:

The first one is an O(n) set and search (n being the number of keys in the map)
首先設(shè)置和查找的時(shí)間復(fù)雜度都是O(n), n是Map內(nèi)鍵的數(shù)量.
since both operations must iterate through the list of keys to find a matching value.
因?yàn)閮蓚€(gè)操作都必須遍歷每一個(gè)鍵以找到匹配的值.

其次數(shù)組會(huì)一直保留著對(duì)元素的引用, 這跟元素是否為引用類型無關(guān), 只要數(shù)組不被銷毀, 元素的引用也不會(huì)被銷毀:

let ele1 = 'ele1';
let ele2 = { key: 'value' };

let arr = [ ele1, ele2 ];

ele1 = null; // 設(shè)置為null脫離當(dāng)前執(zhí)行環(huán)境, 以便回收機(jī)制回收
ele2.key = null;

console.log(arr);
// [ 'ele1', { key: 'null' } ]

前面提到Map內(nèi)部可以通過兩個(gè)數(shù)組實(shí)現(xiàn), 那么意味著在Map需要銷毀前, Map內(nèi)的鍵和值都無法被JavaScript垃圾回收機(jī)制回收, Map可能會(huì)變得臃腫龐大導(dǎo)致內(nèi)存不足(內(nèi)存泄漏).

持有原始對(duì)象引用的映射實(shí)際上意味著對(duì)象不能被垃圾回收, 這可能會(huì)導(dǎo)致意外的內(nèi)存問題.
如果你希望存儲(chǔ)在映射中的對(duì)象具有與原始對(duì)象相同的生命周期, 請(qǐng)考慮使用 WeakMap.

2. WeakMap

WeakMap同Map是鍵值對(duì)的集合, 但它的鍵被弱保持, 即當(dāng)鍵所指的對(duì)象未在其他地方被引用時(shí), 將被垃圾回收機(jī)制回收.
其鍵必須是對(duì)象, 值可以是任意數(shù)據(jù)類型.

也由于這種弱引用實(shí)現(xiàn)的垃圾回收可執(zhí)行, WeakMap內(nèi)元素的存在變得不可預(yù)知(可能垃圾回收機(jī)制目前沒有回收至此處, 但此處應(yīng)當(dāng)回收.), 為了防止執(zhí)行時(shí)出現(xiàn)意外, WeakMap沒有提供枚舉方法.

正由于這樣的弱引用, WeakMap的key是不可枚舉的(沒有方法能給出所有的 key).
如果key可枚舉, 其列表將受垃圾回收機(jī)制的影響, 從而得到不確定的結(jié)果。

但是WeakMap提供的接口與Map相同, 可以通過接口穩(wěn)定的訪問元素.

let ele1 = { key: "value" };

let weak = new WeakMap();
weak.set(ele1, "ele1");

ele1 = null;

console.log(weak); // WeakMap { <items unknown> } 不賦值null此處結(jié)果相同
console.log(weak.get(ele1)); // undefined 銷毀 不賦值null此處為'ele1'

總之, 相比Map, 它更干凈利落, 更節(jié)約內(nèi)存.
但是你如果有枚舉需求, 或者就是需要一直保存著key不回收, 那就用Map.

二、WeakMap原型方法

指明需要何種操作, 并指明需要操作的鍵值對(duì)的key, 直接傳變量即可.

方法描述
WeakMap.prototype.delete(key)刪除WeakMap中與key相匹配的value.
WeakMap.prototype.get(key)返回WeakMap中與key相關(guān)聯(lián)的值, 如果key不存在則返回undefined.
WeakMap.prototype.has(key)返回布爾值, 斷言WeakMap對(duì)象中該key是否存在.
WeakMap.prototype.set(key, value)WeakMap中設(shè)置一組新的鍵值對(duì), 返回設(shè)置完畢后的WeakMap對(duì)象.

總結(jié)

到此這篇關(guān)于JavaScript WeakMap的具體使用的文章就介紹到這了,更多相關(guān)JavaScript WeakMap內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論