javascript
《JavaScript高级程序设计》笔记 - Map与Object的差异与选择
Map與Object的差異與選擇
ES6以前,我們可以使用Object方便高效地完成“鍵/值”式的存儲,但是這種實(shí)現(xiàn)并非沒有問題。因此,TC39委員會專門為“鍵/值”存儲定義了一個規(guī)范,即Map。它是一種新的集合類型,為這門語言帶來了真正地鍵/值存儲機(jī)制。
Object和Map的細(xì)微語法差異
1. 鍵的數(shù)據(jù)類型
與Object只能使用數(shù)值、字符串或符號作為鍵不同,Map可以使用任何JS的數(shù)據(jù)類型作為鍵。
Map內(nèi)部使用嚴(yán)格對象相等的標(biāo)準(zhǔn)來檢查鍵的匹配性。當(dāng)然,與Object類似,映射的值是沒有限制的。
2. 順序與迭代
與Object類型的一個主要差異是,Map實(shí)例會維護(hù)鍵值對的插入順序,這也就意味著可以根據(jù)插入順序進(jìn)行迭代操作。
迭代方式:
1)映射實(shí)例可以提供一個迭代器(Iterator),能以插入順序生成 [key,value] 形式的數(shù)組。可以通過entries()方法(或者Symbol.iterator 屬性,它引用 entries() 方法)取得這個迭代器。
const m = new Map([["key1","val1"],["key2","val2"],["key3","val3"] ]);//Symbol.iterator引用entries()方法 alert(m.entries === m[Symbol.iterator]); //-> true//迭代,使用m[Symbol.iterator]一樣可以 for(let pair of m.entries()) alert(pair); //-> [key1,val1] //-> [key2,val2] //-> [key3,val3]因?yàn)閑ntries()是默認(rèn)迭代器,所以可以直接對映射實(shí)例使用擴(kuò)展操作,把映射轉(zhuǎn)化為數(shù)組:
const m = new Map([["key1","val1"],["key2","val2"],["key3","val3"] ]);console.log([...m]); //-> [[key1,val1],[ley2,val2],[key3,val3]]2)不使用迭代器,而是用回調(diào)方式的話,可以調(diào)用映射的forEach() 方法并傳入回調(diào),依次迭代每個鍵值對。傳入的回調(diào)接收可選的第二個參數(shù),這個參數(shù)用于重寫回調(diào)內(nèi)部this的值:
const m = new Map([["key1","val1"],["key2","val2"],["key3","val3"] ]);m.forEach((val,key) => alert(`${key} -> ${val}`)); // key1 -> val1 // key2 -> val2 // key3 -> val33)keys() 和 values() 分別返回以插入順序生成鍵和值的迭代器。
鍵和值在迭代器遍歷時是可以修改的,但映射內(nèi)部的引用無法修改。當(dāng)然,這并不妨礙修改作為鍵或值的的對象內(nèi)部的屬性,因?yàn)檫@并不影響它們在映射實(shí)例中的身份。
選擇Object還是Map
以下內(nèi)容直接采用紅寶書原話。結(jié)論直接看加粗文本。
對于多數(shù) Web開發(fā)任務(wù)來說,選擇Object還是Map只是個人偏好問題,影響不大。不過,對于在乎內(nèi)存和性能的開發(fā)者來說,對象和映射之間確實(shí)存在顯著的差別。
內(nèi)存占用
Object和Map的工程級實(shí)現(xiàn)在不同瀏覽器間存在明顯差異,但存儲單個鍵值對所占用的內(nèi)存數(shù)都會隨鍵的數(shù)量線性增加。批量添加或刪除鍵/值對則取決于各瀏覽器對該類型內(nèi)存分配的工程實(shí)現(xiàn)不同瀏覽器的情況不同,但給定固定大小的內(nèi)存,Map大約可以比Object多存儲50%的鍵/值對。
插入性能
向Object和Map中插入新鍵/值對的消耗大致相當(dāng),不過插入Map在所有瀏覽器中一般會稍微快一點(diǎn)兒。對這兩個類型來說,插入速度并不會隨著鍵/值對數(shù)量而線性增加。如果代碼涉及大量插入操作,那么顯然Map的性能更佳。
查找速度
與插入不同,從大型Object和Map中查找鍵/值對的性能差異極小,但如果只包含少量鍵/值對,則Object有時候速度更快。在把object當(dāng)成數(shù)組使用的情況下(比如使用連續(xù)整數(shù)作為屬性),瀏覽器引擎可以進(jìn)行優(yōu)化,在內(nèi)存中使用更高效的布局。這對Map來說是不可能的。對這兩個類型而言,查找速度不會隨著鍵/值對數(shù)量增加而線性增加。如果代碼涉及大量查找操作,那么某些情況下可能選擇Object更好一些。
刪除性能
使用delete刪除Object屬性的性能一直以來飽受詬病,目前在很多瀏覽器中仍然如此。為此,出現(xiàn)了一些偽刪除對象屬性的操作,包括把屬性值設(shè)置為undefined或null。但很多時候,這都是一種討厭的或不適宜的折中。而對大多數(shù)瀏覽器引擎來說,Map的 delete() 操作都比插入和查找更快。如果代碼涉及大量刪除操作,那么毫無疑問應(yīng)該選擇Map。
總結(jié)
以上是生活随笔為你收集整理的《JavaScript高级程序设计》笔记 - Map与Object的差异与选择的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么叫时钟漂移(Wander)?时钟漂移
- 下一篇: SCCM 2012 SP1系列(九)配置