current position:Home>Introduction and practice of JS map and weakmap objects

Introduction and practice of JS map and weakmap objects

2021-08-27 08:16:18 Rio_ Kwok

This is my participation 8 The fourth of the yuegengwen challenge 5 God , Check out the activity details :8 Yuegengwen challenge

Map

Map Objects are inserted in the order in which they are inserted , Store key value pairs (key-value) Data in form , Any data type can be used as key perhaps value.

and Object similar , Each key must be unique , If the data type of the key is the original data type, a value comparison is performed , Object types are compared by reference .

Instance attributes

  • size Read-only property , Returns the number of key value pairs

Method

  • set(key, value) Add key value pair
  • get(key) Returns the value associated with this key
  • clear() Remove all key value pairs
  • delete(key) Delete the key value pair equal to this key
  • has(value) Returns whether to include this value
  • entries() Returns a containing Map Iterators in insertion order for all key value pairs in , Each element of the iterator is [key, value] Array of form
  • forEach(callbackFn, thisArg) In order of insertion , Of each key value pair key and value As the second 1 And the 2 Parameter execution callback Method
  • keys() Returns a containing Map Iterators with all keys in the and arranged in insertion order
  • values() Returns a containing Map Iterators with all values in the and arranged in insertion order

Map vs Object

Overview of differences

  • Map The key of can be any data type ,Object The key of can only be a string or Symbol
  • Map Can pass size Get the number of elements ,Object There is no
  • Map Itself is an iterator , You can iterate directly ;Object You need to use Object A static method of an object (keysvaluesentries) To iterate
  • Map serialize (JSON.stringify) Then it became ordinary Object Cause the loss of its own data type , Need to realize , Empathy , String is parsed into JSON Objects are also not supported Map

The insert

Put the test code first :

var m = new Map()
var now = performance.now()
for(let i = 0; i<10000; i++) {
    m.set('m'+i, i)
}
console.log(performance.now() - now)

var o = {}
var now = performance.now()
for(let i = 0; i<10000; i++) {
    o['o'+i] = i
}
console.log(performance.now() - now)
 Copy code 

When the number of inserts is in 1 m ,Map and Object The difference is not significant , Basically all in 3-5ms within .

here we are 10 m ,Map The average duration is 50ms Up and down , Most of them fall on 45-55ms The range of ;Object Average duration 60ms Up and down , Most of them fall on 50-70ms The range of .

here we are 100 m ,Map The average duration is 590ms Up and down , Most of them fall on 500-700ms The range of ;Object Average duration 650ms Up and down , Most of them fall on 550-750ms The range of , Occasionally more than 850ms The situation of .

here we are 500 m ,Map Average duration 3542.4ms, Most of them fall on 3300-3700ms The range of ;Object Average duration 3851.2ms, Most of them fall on 3100-4200ms The range of , Occasionally more than 4800ms The situation of .

here we are 800 m ,Map Average duration 6004.2ms, Most of them fall on 5500-6500ms The range of ;Object Average duration 9171ms, Most of them fall on 8500-9500ms The range of , Occasionally more than 10500ms The situation of .

exceed 1000 Ten thousand times ,Map The average length of time 7582ms,Object It will cause the browser to fake death very often , The comparison ends .

Number of inserts Map Object
10 ten thousand 50ms Up and down 60ms Up and down
100 ten thousand 590ms Up and down 650ms Up and down
500 ten thousand 3542.4ms 3851.2ms
800 ten thousand 6004.2ms 9171ms

Conclusion : In the case of frequent insertion operations ,Map Than Object Better performance , And the time-consuming distribution is more convergent .

Query operation

var m = new Map()
for(let i = 0; i<1000000; i++) {
    m.set('m'+i, i)
}
var now = performance.now()
for(let j = 0; j<1000000; j++) {
  m.get('m'+j)
}
console.log(performance.now() - now)

var o = {}
for(let i = 0; i<1000000; i++) {
    o['o'+i] = i
}
var now = performance.now()
for(let j = 0; j<1000000; j++) {
  o['o'+j]
}
console.log(performance.now() - now)
 Copy code 
Query times Map Object
10 ten thousand 24.6ms 41.9ms
50 ten thousand 52.4ms 170.5ms
100 ten thousand 83.2ms 354.6ms
500 ten thousand 336.9ms 2162.2ms

Conclusion : In the case of frequent query operations ,Map Than Object Better performance , The time-consuming gap of 100000 levels is 2-4 times , The million level time gap is 4-6 About times

Common operations

Initialize assignment

Use a two-dimensional array for initialization and assignment , Form like [[key0, value0], [key1, value1], ...]

var m = new Map([[123, 'abc'], ['aaa', true]])
console.log(m)
// output: {123 => "abc", "aaa" => true}
 Copy code 

clone

From a Map Object to clone a new Map object , You can see from the following code , Object data type key, Even if the object content changes , It will not affect the query . Again , Object data type value, Just cloned the pointer of the object .

var o = {name: 'Jack'}
var o2 = {msg: 'hello'}
var m = new Map([['k', o2], ['a', 123]])
m.set(o, [1, 2, 3])
var m2 = new Map(m)
o2.msg = 'hi'
console.log(m)
// output: {"k" => {…}, "a" => 123, {…} => Array(3)}
console.log(m2)
// output: {"k" => {…}, "a" => 123, {…} => Array(3)}
console.log(m === m2)
// output: false
console.log(m.get('k') === m2.get('k'))
// output: true
console.log(m.get('k'))
// output: {msg: 'hi'}
m.delete('k')
m2.set('k', 'v')
console.log(m)
// output: {"a" => 123, {…} => Array(3)}
console.log(m2)
// output: {"k" => "v", "a" => 123, {…} => Array(3)}
o.name = 'David'
console.log(m.get(o))
// output: [1, 2, 3]
console.log(m2.get(o))
// output: [1, 2, 3]
 Copy code 

Merge

Two Map The merger of , Cannot be directly passed in as a parameter when creating , It needs to be converted into a two-dimensional array , And the same key , Subject to the following .

var m = new Map([['x', 'abc'], ['y', 233]])
var m2 = new Map([['x', 666], ['z', 'hhh']])
var m3= new Map(m, m2)
var m4 = new Map([...m, ...m2])
console.log(m3)
// output: {"x" => "abc", "y" => 233}
console.log(m4)
// output: {"x" => 666, "y" => 233, "z" => "hhh"}
 Copy code 

WeakMap

and Map Different ,WeakMap Object to store key value pairs (key-value) The key , Can only be object data type .

An error occurred while trying to insert a key of a non object data type , Will trigger an error .

Uncaught TypeError: Invalid value used as weak map key
    at WeakMap.set (<anonymous>)
    at <anonymous>:1:3
 Copy code 

WeakMap vs Map The difference of

The differences between the two are mainly concentrated in two points :

  • WeakMap Of key Only objects can be stored , and Map No matter what key still value, Can store any data type
  • WeakMap Stored objects , If there are no other references , This object will be garbage collected . This is called Weak Why , It also means ,WeakMap It can't be enumerated , There is no size.

stay Chrome Developer tools Console Panel test the following code :

Method

be relative to Map,WeakMap Its weak reference feature causes its methods to have only the following 4 individual :

  • set(key, value) Add key value pair
  • get(key) Returns the value associated with this key
  • delete(key) Delete the key value pair equal to this key
  • has(value) Returns whether to include this value

Practical scenarios

  • Yes DOM Operate and hold DOM node , Use WeakMap You can make DOM After the node is deleted by other code logic , It is convenient for memory to be recycled , Prevent memory leaks
  • Babel compile ES6 Private properties of the following classes , Refer to my previous article TypeScript The private field of the object in a small condition Part of it

Compatibility

Last , Let's take a look at browser compatibility .

Map

Screen Shot 2021-08-23 at 12.40.48 AM.png

WeakMap

Screen Shot 2021-08-23 at 12.40.30 AM.png

Basically , Most modern browsers support Map and WeakMap, Most usage scenarios can be used safely .

copyright notice
author[Rio_ Kwok],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210827081612817c.html

Random recommended