色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

JavaScript中Object、map、weakmap的區(qū)別分析

瀏覽:64日期:2023-10-06 09:48:43
前言

ECMAScript 6以前,在JavaScript中實(shí)現(xiàn)“鍵/值”式存儲(chǔ)可以使用Object來(lái)方便高效地完成,也就是使用對(duì)象屬性作為鍵,再使用屬性來(lái)引用值。但這種實(shí)現(xiàn)并非沒(méi)有問(wèn)題,為此TC39委員會(huì)專門為“鍵/值”存儲(chǔ)定義了一個(gè)規(guī)范。作為ECMAScript 6的新增特性,Map是一種新的集合類型,為這門語(yǔ)言帶來(lái)了真正的鍵/值存儲(chǔ)機(jī)制。Map的大多數(shù)特性都可以通過(guò)Object類型實(shí)現(xiàn),但二者之間還是存在一些細(xì)微的差異。具體實(shí)踐中使用哪一個(gè),還是值得細(xì)細(xì)甄別。

一、map 的使用

初始化

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

object 的創(chuàng)建方式 const object = {}const object1 = new Object()const object2 = Object.create({}) map 的創(chuàng)建方式//使用new關(guān)鍵字const m0 = new Map;// 使用嵌套數(shù)組初始化映射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// 映射期待的鍵/值對(duì),無(wú)論是否提供const m3 = new Map([[]]);alert(m3.has(undefined)); // truealert(m3.get(undefined)); // undefined

map鍵類型

與Object只能使用數(shù)值、字符串或符號(hào)作為鍵不同,Map可以使用任何JavaScript數(shù)據(jù)類型作為鍵。Map內(nèi)部使用SameValueZero比較操作(ECMAScript規(guī)范內(nèi)部定義,語(yǔ)言中不能使用),基本上相當(dāng)于使用嚴(yán)格對(duì)象相等的標(biāo)準(zhǔn)來(lái)檢查鍵的匹配性。與Object類似,映射的值是沒(méi)有限制的。

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比較意味著獨(dú)立實(shí)例不沖突 alert(m.get(function() {})); // undefined

順序與迭代

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

const m = new Map([ ['key1', 'val1'], ['key2', 'val2'], ['key3', 'val3']]);alert(m.entries === m[Symbol.iterator]); // truefor (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

對(duì)于多數(shù)Web開(kāi)發(fā)任務(wù)來(lái)說(shuō),選擇Object還是Map只是個(gè)人偏好問(wèn)題,影響不 大。不過(guò),對(duì)于在乎內(nèi)存和性能的開(kāi)發(fā)者來(lái)說(shuō),對(duì)象和映射之間確實(shí)存在顯著的 差別。

1.內(nèi)存占用

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

2.插入性能

向Object和Map中插入新鍵/值對(duì)的消耗大致相當(dāng),不過(guò)插入Map在所有瀏覽器中一般會(huì)稍微快一點(diǎn)兒。對(duì)這兩個(gè)類型來(lái)說(shuō),插入速度并不會(huì)隨著鍵/值對(duì)數(shù)量而線性增加。如果代碼涉及大量插入操作,那么顯然Map的性能更佳。

3.查找速度

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

4.刪除性能

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

三、weakMap

ECMAScript 6新增的“弱映射”(WeakMap)是一種新的集合類型,為這門語(yǔ)言帶來(lái)了增強(qiáng)的鍵/值對(duì)存儲(chǔ)機(jī)制。WeakMap是Map的“兄弟”類型,其API也是Map的子集。WeakMap中的“weak”(弱),描述的是JavaScript垃圾回收程序?qū)Υ叭跤成洹敝墟I的方式。

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

//會(huì)被回收const wm = new WeakMap();wm.set({}, 'val');//不會(huì)被回收const wm2 = new WeakMap();const container = { key: {}};wm2.set(container.key, 'val');function removeReference() { container.key = null;}

在vm中,set()方法初始化了一個(gè)新對(duì)象并將它用作一個(gè)字符串的鍵。因?yàn)闆](méi)有指向這個(gè)對(duì)象的其他引用,所以當(dāng)這行代碼執(zhí)行完成后,這個(gè)對(duì)象鍵就會(huì)被當(dāng)作垃圾回收。然后,這個(gè)鍵/值對(duì)就從弱映射中消失了,使其成為一個(gè)空映射。在這個(gè)例子中,因?yàn)橹狄矝](méi)有被引用,所以這對(duì)鍵/值被破壞以后,值本身也會(huì)成為垃圾回收的目標(biāo)。而在vm1中,container對(duì)象維護(hù)著一個(gè)對(duì)弱映射鍵的引用,因此這個(gè)對(duì)象鍵不會(huì)成為垃圾回收的目標(biāo)。不過(guò),如果調(diào)用了removeReference(),就會(huì)摧毀鍵對(duì)象的最后一個(gè)引用,垃圾回收程序就可以把這個(gè)鍵/值對(duì)清理掉。

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

const key1 = {id: 1}, key2 = {id: 2}, key3 = {id: 3};// 使用嵌套數(shù)組初始化弱映射const wm1 = new WeakMap([ [key1, 'val1'], [key2, 'val2'], [key3, 'val3']]);alert(wm.get(key1)); // val1alert(wm.get(key2)); // val2alert(wm.get(key3)); // val3// 原始值可以先包裝成對(duì)象再用作鍵const stringKey = new String('key1');const wm3 = new WeakMap([ stringKey, 'val1']);alert(wm3.get(stringKey)); // 'val1'四、使用weakMap的場(chǎng)景

WeakMap實(shí)例與現(xiàn)有JavaScript對(duì)象有著很大不同,可能一時(shí)不容易說(shuō)清楚應(yīng)該怎么使用它。這個(gè)問(wèn)題沒(méi)有唯一的答案,但已經(jīng)出現(xiàn)了很多相關(guān)策略。

DOM節(jié)點(diǎn)元數(shù)據(jù)因?yàn)閃eakMap實(shí)例不會(huì)妨礙垃圾回收,所以非常適合保存關(guān)聯(lián)元數(shù)據(jù)。如以下代碼所示,下面的例子使用的是WeakMap,當(dāng)節(jié)點(diǎn)從DOM樹(shù)中被刪除后,垃圾回收程序就可以立即釋放其內(nèi)存(假設(shè)沒(méi)有其他地方引用這個(gè)對(duì)象):

const wm = new WeakMap();const loginButton = document.querySelector(’#login’);// 給這個(gè)節(jié)點(diǎn)關(guān)聯(lián)一些元數(shù)據(jù)wm.set(loginButton, {disabled: true});總結(jié)

以上就是object、map、weakmap的相關(guān)使用和區(qū)別了。其實(shí)在大多數(shù)情況下,object和map使用是沒(méi)有什么區(qū)別的,但是如果你需要大量的插入和查找刪除,或者需要使用對(duì)象作為鍵值的話,使用map是比較優(yōu)的選擇。另外weakMap在使用的對(duì)象可能會(huì)被動(dòng)態(tài)刪除的情況下,比map具有優(yōu)化內(nèi)存的優(yōu)勢(shì)。

以上就是JavaScript中Object、map、weakmap的區(qū)別分析的詳細(xì)內(nèi)容,更多關(guān)于JavaScript中Object、map、weakmap區(qū)別的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 暖暖免费高清日本一区二区三区 | 国产日韩精品欧美一区视频 | 成人欧美一区二区三区视频xxx | 欧美不卡视频 | 久久国内精品 | 毛片大全在线 | 超矿碰人人超人人看 | 色视频网站大全免费 | 九九九九热精品视频 | 亚洲一区免费在线观看 | 亚洲欧洲日产国码二区首页 | 久久久久久久网站 | 亚洲精品中文字幕久久久久久 | 香港免费毛片 | 亚洲成aⅴ人片在线影院八 亚洲成av人片在线观看 | 国产精品美女久久福利网站 | 欧美在线视 | 国自产精品手机在线视频香蕉 | 一级毛片视频播放 | 国产成人禁片免费观看视频 | 欧美第一页草草影院浮力 | 成人网视频在线观看免费 | 国产三级日产三级日本三级 | 国产欧美精品一区二区三区 | 国产精品久久毛片蜜月 | 欧美性妇 | 九九视频在线观看视频6偷拍 | 青青草国产一区二区三区 | 久久久精品一区二区三区 | 国产精品成人一区二区 | 欧美一级在线全免费 | 亚洲国产精品成人午夜在线观看 | 美国一级片在线 | 免费一级毛片在线播放不收费 | 亚洲成年人在线观看 | 亚洲天堂视频网站 | 久久精品国产欧美成人 | 精品久久久久久影院免费 | 国产成人免费高清视频 | 狠狠色丁香久久综合网 | 国内xxxx乱子另类 |