[Javascript Tips] Using Map over Object

In Javascript, if you are using Object to store key-valeu pairs while you will be adding and deleting keys frequently, then you should use Map instead.

Because Map have optimzation for deletion but Object has not.

const eventsMap = {}
eventsMap[myEvent.id] = myEvent

delete eventsMap[myEvent.id] // slower

const eventsMap = new Map()

eventsMaps.set(myEvent.id, myEvent)
eventsMaps.delete(myEvent.id) // faster

 

No polluted built-in values

Other issues, for example, Object are polluted with tons of keys built into them already.

 

All those built in props have value already:

const eventsMap = {}
eventsMap.valueOf() // {}

 

But for Map, you don't have this problem:

const eventsMap = new Map()
eventsMap.get(valueOf) // undefined

 

WeakMap

for Map, you can use any value as key, even DOMnode or an empty object or any reference

const metadata = new Map()
metadata.set({}, 'value')
metadata.set(DOMNode, 'value')
metadata.set(myEvent, {...})

But there is one problem, for example metadata.set(myEvent, {...}), if for myEvent, any reference to it has been removed, it should be garbage collected, but because of Map is holding the reference, it might cause memory leak.

That's why we can use WeakMap

const metadata = new WeakMap()
metadata.set(myEvent, {...})

If other reference to myEventhas been removed,  it will be automaticlly garbage collected as well to prevent memory leak.

 

Iterating over Object vs Map

When interating over an object, you have to do this:

const eventsMap = {}

// option 1: eventsMap.hasOwnProperty
// problem: it can be overwritten
for (const key in eventsMap) {
  if (eventsMap.hasOwnProperty(key)) {
    // logic here
  }
}

// option 2: Object.property.hasOwnProperty
// safer than option 1
// problem: too urgly
for (const key in eventsMap) {
  if (Object.property.hasOwnProperty.call(eventsMap, key)) {
    // logic here
  }
}

// option 3: Object.keys
Object.keys(eventMap).map(key => {...})

 

Map doesn't have those problem, and Map can preserve the order of the keys, and becasue Map is iterable, you can use destructuring to grab the first key and value

const eventsMap = new Map()
const [[firstKey, firstValue]] = eventsMap

 

posted @ 2023-02-21 16:08  Zhentiw  阅读(13)  评论(0编辑  收藏  举报