本文記錄 ES6 中新增的 Map 對象轉(zhuǎn)換為 Object 的幾種方式,以及測試各種方式轉(zhuǎn)換的性能。
const map = new Map()
map.set('??', 'basketball')
map.set('???', 'soccer')
map.set('??', 'baseball')
map.set('??', 'tennis')
第一種方式
首先我們準備一個 map 對象,接下來看第一種方式:
const obj = Array.from(map).reduce((obj, [key, value]) =>
Object.assign(obj, { [key]: value} )
, {})
console.log(obj) // { '??': 'basketball', '???': 'soccer', '??': 'baseball', '??': 'tennis' }
但是第一種方式在數(shù)據(jù)量過大的時候,在每個迭代中創(chuàng)建一個新對象(使用 Object.assign)時,性能會受到影響,還有一點是 Map 的 key 可以是非字符串的鍵,轉(zhuǎn)換成字面量的 object 則不可以。
第二種方式
于是我們來看第二種方法,來解決第一種方法可能會遇到的性能問題:
const obj = Array.from(map).reduce((obj, [key, value]) => {
obj[key] = value
return obj
}, {})
console.log(obj) // { '??': 'basketball', '???': 'soccer', '??': 'baseball', '??': 'tennis' }
使用 Array.from(map).reduce(fn, {}), 你可以安全的在累加器中操作 object
第三種方式
如果你熟悉 ES6 中的寫法,你也可以用第三種 ES6 的方式來替換 Array.from(map):
const obj = [...map.entries()].reduce((obj, [key, value]) => (obj[key] = value, obj), {})
console.log(obj) // { '??': 'basketball', '???': 'soccer', '??': 'baseball', '??': 'tennis' }
用 ES6 的寫法,我們只需要用一行代碼就可以完成任務(wù)啦,簡潔控的最愛。
第四種方式
而最后一種方法,也是跟擴展運算符相關(guān)的一種寫法:
const obj = Array.from(map.entries()).reduce((main, [key, value]) => ({...main, [key]: value}), {})
console.log(obj) // { '??': 'basketball', '???': 'soccer', '??': 'baseball', '??': 'tennis' }
這行代碼乍一看完全沒問題,因為使用了擴展運算符還有點優(yōu)雅的感覺,并且也是一行代碼解決了戰(zhàn)斗,但是在后面的性能測試過程中,第四種方法當真是讓人大跌眼鏡。
性能測試
現(xiàn)在我把四種寫法放到一起,并且我創(chuàng)建一個擁有 10000 個 key 的 Map 來做轉(zhuǎn)換,測試一下四種寫法的性能。
// 創(chuàng)建一個較大的 map
for (let i = 0; i < 10000; i++) {
map.set(`a${i}`, i)
}
// MapConvertToObj1: 16.381ms
// MapConvertToObj2: 5.661ms
// MapConvertToObj3: 4.903ms
// MapConvertToObj4: 20344.747ms
看到這 4 種方式的性能輸出,是不是大跌眼鏡呢?并且第一種方式,果然是因為 Object.assign() 的用法存在性能開銷,總體比第二種和第三種慢一點。
如果我們把 key 的數(shù)量減少到 1000 個,第四種方式會不會好一點呢?
// MapConvertToObj1: 3.742ms
// MapConvertToObj2: 1.140ms
// MapConvertToObj3: 0.874ms
// MapConvertToObj4: 185.745ms
可以看到第四種方式還是沒有太多起色,而多次測試下來,第三種方式是轉(zhuǎn)換速度最快的,推薦大家以后 Map 轉(zhuǎn)換成對象時,使用第三種方式來轉(zhuǎn)換哦,又快又優(yōu)雅。