激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - JavaScript中Object、map、weakmap的區別分析

JavaScript中Object、map、weakmap的區別分析

2021-12-13 20:26有頭發的小D JavaScript

這篇文章主要介紹了JavaScript中Object、map、weakmap的區別分析,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下

前言

ECMAScript 6以前,在JavaScript中實現“鍵/值”式存儲可以使用Object來方便高效地完成,也就是使用對象屬性作為鍵,再使用屬性來引用值。但這種實現并非沒有問題,為此TC39委員會專門為“鍵/值”存儲定義了一個規范。作為ECMAScript 6的新增特性,Map是一種新的集合類型,為這門語言帶來了真正的鍵/值存儲機制。Map的大多數特性都可以通過Object類型實現,但二者之間還是存在一些細微的差異。具體實踐中使用哪一個,還是值得細細甄別。

一、map 的使用

初始化

object 可以使用字面量、構造函數、Object.crate的形式創建。而map 只能通過new 關鍵字和構造函數創建。對于map如果想在創建的同時初始化實例,可以給Map構造函數傳入一個可迭代對象,需要包含鍵/值對數組。可迭代對象中的每個鍵/值對都會按照迭代順序插入到新映射實例中:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
object 的創建方式
 
const object = {}
const object1 = new Object()
const object2 = Object.create({})
 
map 的創建方式
//使用new關鍵字
const m0 = new Map;
// 使用嵌套數組初始化映射
const m1 = new Map([
 ["key1", "val1"],
 ["key2", "val2"],
 ["key3", "val3"]
]);
alert(m1.size); // 3
// 使用自定義迭代器初始化映射
const m2 = new Map({
[Symbol.iterator]: function*() {
 yield ["key1", "val1"];
 yield ["key2", "val2"];
 yield ["key3", "val3"];
}
});
alert(m2.size); // 3
// 映射期待的鍵/值對,無論是否提供
const m3 = new Map([[]]);
alert(m3.has(undefined)); // true
alert(m3.get(undefined)); // undefined

map鍵類型

與Object只能使用數值、字符串或符號作為鍵不同,Map可以使用任何JavaScript數據類型作為鍵。Map內部使用SameValueZero比較操作(ECMAScript規范內部定義,語言中不能使用),基本上相當于使用嚴格對象相等的標準來檢查鍵的匹配性。與Object類似,映射的值是沒有限制的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
const m = new Map();
const functionKey = function() {};
const symbolKey = Symbol();
const objectKey = new Object();
m.set(functionKey, "functionValue");
m.set(symbolKey, "symbolValue");
m.set(objectKey, "objectValue");
alert(m.get(functionKey)); // functionValue
alert(m.get(symbolKey)); // symbolValue
alert(m.get(objectKey)); // objectValue
// SameValueZero比較意味著獨立實例不沖突
alert(m.get(function() {})); // undefined

順序與迭代

與Object類型的一個主要差異是,Map實例會維護鍵值對的插入順序,因此可以根據插入順序執行迭代操作。映射實例可以提供一個迭代器(Iterator),能以插入順序生成[key,value]形式的數組。可以通過entries()方法(或者Symbol.iterator屬性,它引用entries())取得這個迭代器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const m = new Map([
 ["key1", "val1"],
 ["key2", "val2"],
 ["key3", "val3"]
]);
alert(m.entries === m[Symbol.iterator]); // true
for (let pair of m.entries()) {
 alert(pair);
}
// [key1,val1]
// [key2,val2]
// [key3,val3]
for (let pair of m[Symbol.iterator]()) {
 alert(pair);
}
// [key1,val1]
// [key2,val2]
// [key3,val3]

二、選擇Object還是Map

對于多數Web開發任務來說,選擇Object還是Map只是個人偏好問題,影響不 大。不過,對于在乎內存和性能的開發者來說,對象和映射之間確實存在顯著的 差別。

1.內存占用

Object和Map的工程級實現在不同瀏覽器間存在明顯差異,但存儲單個鍵/值對所占用的內存數量都會隨鍵的數量線性增加。批量添加或刪除鍵/值對則取決于各瀏覽器對該類型內存分配的工程實現。不同瀏覽器的情況不同,但給定固定大小的內存,Map大約可以比Object多存儲50%的鍵/值對。

2.插入性能

向Object和Map中插入新鍵/值對的消耗大致相當,不過插入Map在所有瀏覽器中一般會稍微快一點兒。對這兩個類型來說,插入速度并不會隨著鍵/值對數量而線性增加。如果代碼涉及大量插入操作,那么顯然Map的性能更佳。

3.查找速度

與插入不同,從大型Object和Map中查找鍵/值對的性能差異極小,但如果只包含少量鍵/值對,則Object有時候速度更快。在把Object當成數組使用的情況下(比如使用連續整數作為屬性),瀏覽器引擎可以進行優化,在內存中使用更高效的布局。這對Map來說是不可能的。對這兩個類型而言,查找速度不會隨著鍵/值對數量增加而線性增加。如果代碼涉及大量查找操作,那么某些情況下可能選擇Object更好一些。

4.刪除性能

使用delete刪除Object屬性的性能一直以來飽受詬病,目前在很多瀏覽器中仍然如此。為此,出現了一些偽刪除對象屬性的操作,包括把屬性值設置為undefined或null。但很多時候,這都是一種討厭的或不適宜的折中。而對大多數瀏覽器引擎來說,Map的delete()操作都比插入和查找更快。如果代碼涉及大量刪除操作,那么毫無疑問應該選擇Map

三、weakMap

ECMAScript 6新增的“弱映射”(WeakMap)是一種新的集合類型,為這門語言帶來了增強的鍵/值對存儲機制。WeakMap是Map的“兄弟”類型,其API也是Map的子集。WeakMap中的“weak”(弱),描述的是JavaScript垃圾回收程序對待“弱映射”中鍵的方式。

weakcMap 的弱
WeakMap中“weak”表示弱映射的鍵是“弱弱地拿著”的。意思就是,這些鍵不屬于正式的引用,不會阻止垃圾回收,當瀏覽器需要回收內存時這些鍵是可能會被回收的。但要注意的是,弱映射中值的引用可不是“弱弱地拿著”的。只要鍵存在,鍵/值對就會存在于映射中,并被當作對值的引用,因此就不會被當作垃圾回收。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
//會被回收
const wm = new WeakMap();
wm.set({}, "val");
 
//不會被回收
const wm2 = new WeakMap();
const container = {
 key: {}
};
wm2.set(container.key, "val");
function removeReference() {
 container.key = null;
}

在vm中,set()方法初始化了一個新對象并將它用作一個字符串的鍵。因為沒有指向這個對象的其他引用,所以當這行代碼執行完成后,這個對象鍵就會被當作垃圾回收。然后,這個鍵/值對就從弱映射中消失了,使其成為一個空映射。在這個例子中,因為值也沒有被引用,所以這對鍵/值被破壞以后,值本身也會成為垃圾回收的目標。
而在vm1中,container對象維護著一個對弱映射鍵的引用,因此這個對象鍵不會成為垃圾回收的目標。不過,如果調用了removeReference(),就會摧毀鍵對象的最后一個引用,垃圾回收程序就可以把這個鍵/值對清理掉。

weakMap使用
WeakMap的初始化與map并沒有什么太大的差別,需要注意的是weakMap只能使用object類型的鍵,這與weakMap的作用是息息相關的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const key1 = {id: 1},
 key2 = {id: 2},
 key3 = {id: 3};
// 使用嵌套數組初始化弱映射
const wm1 = new WeakMap([
 [key1, "val1"],
 [key2, "val2"],
 [key3, "val3"]
]);
alert(wm.get(key1)); // val1
alert(wm.get(key2)); // val2
alert(wm.get(key3)); // val3
 
// 原始值可以先包裝成對象再用作鍵
const stringKey = new String("key1");
const wm3 = new WeakMap([
 stringKey, "val1"
]);
alert(wm3.get(stringKey)); // "val1"

四、使用weakMap的場景

WeakMap實例與現有JavaScript對象有著很大不同,可能一時不容易說清楚應該怎么使用它。這個問題沒有唯一的答案,但已經出現了很多相關策略。

DOM節點元數據
因為WeakMap實例不會妨礙垃圾回收,所以非常適合保存關聯元數據。如以下代碼所示,下面的例子使用的是WeakMap,當節點從DOM樹中被刪除后,垃圾回收程序就可以立即釋放其內存(假設沒有其他地方引用這個對象):

?
1
2
3
4
const wm = new WeakMap();
const loginButton = document.querySelector('#login');
// 給這個節點關聯一些元數據
wm.set(loginButton, {disabled: true});

總結

以上就是object、map、weakmap的相關使用和區別了。其實在大多數情況下,object和map使用是沒有什么區別的,但是如果你需要大量的插入和查找刪除,或者需要使用對象作為鍵值的話,使用map是比較優的選擇。另外weakMap在使用的對象可能會被動態刪除的情況下,比map具有優化內存的優勢。

以上就是JavaScript中Object、map、weakmap的區別分析的詳細內容,更多關于JavaScript中Object、map、weakmap區別的資料請關注服務器之家其它相關文章!

原文鏈接:https://juejin.cn/post/6905297673494986759

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本在线一区二区 | 欧美黄色一级带 | 久久草在线视频国产 | 久久精品99国产国产精 | 国产精品麻豆91 | 成人福利视频在 | 成人超碰97| 成人午夜免费看 | 欧美精品一级片 | 手机免费看一级片 | 国产成人精品区一区二区不卡 | 香蕉视频99 | 欧美一区二区三区中文字幕 | 久久99精品国产99久久6男男 | 日韩在线视频二区 | 高清在线国产 | 欧美日韩影视 | 久久久www视频 | 九九热视频这里只有精品 | 一级成人毛片 | 一级片在线免费观看 | 久久国产精品二国产精品中国洋人 | 欧美视频国产精品 | 日韩视频高清 | 欧美视频国产精品 | 91av99| 最近免费观看高清韩国日本大全 | 伊人手机在线观看 | h视频在线观看免费 | 中国美女一级黄色大片 | 麻豆视频在线免费观看 | 国产一区二区三区手机在线 | 99久久久精品免费观看国产 | 日本特级a一片免费观看 | 亚洲精品久久久久久下一站 | 最近免费观看高清韩国日本大全 | 久草在线观看福利 | 午夜在线视频一区二区三区 | 91网站在线播放 | 亚洲av毛片在线观看 | 国产精品久久久久久久久久久天堂 |