<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
假設現有場景,開發一個網站,需要提供日語、漢語、韓語三種語言,我們可以定義一個字典去管理。
const dictionary = { 'ja': { 'Ninjas for hire': '忍者を僱う', }, 'zh': { 'Ninjas for hire': '忍者出租', }, 'ko': { 'Ninjas for hire': '고용 닌자', } } console.log(dictionary.ja['Ninjas for hire']) // 忍者を僱う console.log(dictionary.zh['Ninjas for hire']) // 忍者出租 console.log(dictionary.ko['Ninjas for hire']) // 고용 닌자
這樣我們就把不同語言的字典管理起來了。但是,當我們試圖存取 constroctor
屬性,問題就出現了。
console.log(dictionary.ko['constructor']) // ƒ Object() { [native code] }
對於不存在的屬性,我們期望得到 undefined
,結果卻通過原型鏈存取到了未定義的屬性,原型物件的 constructor
屬性,指向建構函式。
此處有一個解決辦法是把原型設定為 null
Object.setPrototypeOf(dictionary.ko, null) console.log(dictionary.ko['constructor']) // undefined
假設需要將物件的 key
對映為 html
節點。我們寫如下程式碼:
/* html部分 <div id="firstElement"></div> <div id="secondElement"></div> */ const firstElement = document.getElementById('firstElement') const secondElement = document.getElementById('secondElement') const map = {} map[firstElement] = { data: 'firstElement' } map[secondElement] = { data: 'secondElement' } console.log(map[firstElement].data) // secondElement console.log(map[secondElement].data) // secondElement
第一個元素的資料被覆蓋了,原因是物件中的 key 只能是字串型別,當我們沒有使用字串型別時,它會隱式呼叫 toString
() 函數進行轉換。於是兩個 html 元素都被轉為字串 [object HTMLDivElement]
。
物件的鍵也可以為 Symbol
,不過在 for..in
遍歷和 Object.keys()
以及用 JSON.stringify()
進行序列化的時候,都會忽略為 Symbol
的鍵。
Map
可以使用任何 JavaScript
資料型別作為鍵
function People(name) { this.name = name } const zhangsan = new People('zhangsan') const xiaoming = new People('xiaoming') const lihua = new People('lihua') // 建立 Map const map = new Map() // 建立 Map 並進行初始化 將二維鍵值對陣列轉換成一個Map物件 const map1 = new Map([ ['key1', 'val1'], ['key2', 'val2'], ]) // 將 Map 轉為二維陣列 console.log(Array.from(map1)) // [ [ 'key1', 'val1' ], [ 'key2', 'val2' ] ] // 設定鍵值對映關係 map.set(zhangsan, { region: 'HB' }) map.set(xiaoming, { region: 'HN' }) // 根據 key 獲取對應值 console.log(map.get(zhangsan)) // { region: 'HB' } console.log(map.get(xiaoming)) // { region: 'HN' } // 獲取不存在的 key 得到 undefined console.log(map.get(lihua)) // undefined // 通過 has 函數判斷指定 key 是否存在 console.log(map.has(lihua)) // false console.log(map.has(xiaoming)) // true // map儲存對映個數 console.log(map.size) // 2 // delete 刪除 key map.delete(xiaoming) console.log(map.has(xiaoming)) // false console.log(map.size) // 1 // clear 清空 map map.clear() console.log(map.size) // 0
Map 可以確保遍歷的順序和插入的順序一致
const zhangsan = { name: 'zhangsan' } const xiaoming = { name: 'xiaoming' } const map = new Map() map.set(zhangsan, { region: 'HB' }) map.set(xiaoming, { region: 'HN' }) // 每個鍵值對返回的是 [key, value] 的陣列 for (let item of map) { // = for (let item of map.entries()) { console.log(item) // [ { name: 'zhangsan' }, { region: 'HB' } ] // [ { name: 'xiaoming' }, { region: 'HN' } ] } // 遍歷 key for (let key of map.keys()) { console.log(key) // { name: 'zhangsan' } // { name: 'xiaoming' } } // 遍歷 value for (let key of map.values()) { console.log(key) // { region: 'HB' } // { region: 'HN' } } // 使用 forEach() 方法迭代 Map map.forEach(function(value, key) { console.log(key, value) // { name: 'zhangsan' } { region: 'HB' } // { name: 'xiaoming' } { region: 'HN' } })
Map
內部使用 SameValueZero
比較操作。
關於SameValue
和 SameValueZero
SameValue (Object.is()
) 和嚴格相等(===)相比,對於 NaN 和 +0,-0 的處理不同
Object.is(NaN, NaN) // true Object.is(0, -0) // false
SameValueZero
與 SameValue
的區別主要在於 0 與 -0 是否相等。
map.set(NaN, 0) map.set(0, 0) console.log(map.has(NaN)) // true console.log(map.has(-0)) // true
Map 能像陣列一樣被複制
let original = new Map([ [1, {}] ]) let clone = new Map(original) // 克隆 Map console.log(clone.get(1)); // {} console.log(original === clone) // false console.log(original.get(1) === clone.get(1)) // true
多個 Map 合併
let first = new Map([ [1, 'one'], [2, 'two'], [3, 'three'], ]); let second = new Map([ [1, 'uno'], [2, 'dos'] ]); // 合併兩個 Map 物件時,如果有重複的鍵值,則後面的會覆蓋前面的。 // 展開運運算元本質上是將 Map 物件轉換成陣列。 let merged = new Map([...first, ...second]); console.log(merged.get(1)); // uno console.log(merged.get(2)); // dos console.log(merged.get(3)); // three
Map
無法被序列化,如果試圖用 JSON.stringify
獲得 Map 的 JSON 的話,只會得到 "{}"。
由於 Map 的鍵可以是任意資料型別,而 JSON 僅允許將字串作為鍵,所以一般情況下無法將 Map 轉為 JSON。
不過可以通過下面的方式去嘗試序列化一個 Map:
// 初始化 Map(1) {"key1" => "val1"} const originMap = new Map([['key1', 'val1']]) // 序列化 "[["key1","val1"]]" const mapStr = JSON.stringify(Array.from(originMap.entries())) // 反序列化 Map(1) {"key1" => "val1"} const cloneMap = new Map(JSON.parse(mapStr))
記憶體佔用
不同瀏覽器的情況不同,但給定固定大小的記憶體,Map
大約可以比 Object
多儲存 50% 的鍵/值對。
插入效能
Map 略快,如果涉及大量操作,建議使用 Map
。
查詢速度
效能差異極小,但如果只包含少量鍵/值對,則 Object
有時候速度更快。Object
作為陣列使用時瀏覽器會進行優化。如果涉及大量查詢操作,選擇 Object 會更好一些。
刪除效能
如果程式碼涉及大量的刪除操作,建議選擇 Map
。
到此這篇關於JavaScript
中有了Object
為什麼還需要 Map 呢的文章就介紹到這了,更多相關JavaScript Map
內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45