Set and Map are new data structures in ES6. The values of members are unique and non-duplicate.

The Set element is unique

A Set object is a collection of values whose elements are unique, like an array.

Note that unique values are not the same as the === operator algorithm. -0 +0 is two values, and -0\+0 is the same. NaN are treated as the same value,

Consturctor API

  • Add returns a Set object, so you can chain xx.add().add(3) to add elements
  • Delete returns Boolean results
  • Here,entriesReturns a new iterator object with each key and value equal.
  • Set.prototype.forEach(callbackFn[, thisArg])If thisArg argument is provided, this in the callback will be that argument.

If you have an iterator, you can use for… Of traverses

for (let item of mySet) console.log(item); // key === value For (let [key, value] of myset.entries ()) console.log(key, value)Copy the code

Interchange of set and Array

Let the set = new set ([1, 2, 3]) set [...] / / [1, 2, 3] Array. The from (set)Copy the code

Find the intersection, union, difference set, array deduplication

// Intersection let intersection = new Set([...set1]. Filter (x => set2.has(x))) let union = new Set([...set1, ...set2]) let difference = new Set([...set1].filter(x => ! set2.has(x)))Copy the code

If Set is passed a string, it breaks //

Array.from(new Set('Hello')) // ['H', 'e', 'l', 'l', 'o']
Copy the code

How to modify?

2. Map stores key-value pairs and has an insertion order

The Map object holds key-value pairs and can remember the original insertion order of the keys. Any value (object or raw value) can be a key or a value. Key equality is the same as on set.

Map and Object comparison:

Compare the options Map Object
Key name conflict Map has no explicit keys by default Likely to conflict with the stereotype’s key name
The type of the key Map keys can be any value, function, object, or any primitive type Object must be a string or symbol
size Returns the number of key-value pairs The object keys to read
The iteration Maps are iterable and can be iterated over directly (for… Of). for… In or keys
performance Frequent add or deletePerforms better in key-value pairs There is no

The constructor of the API

  • Use set to add a key to a Map object. Returns a Map object, chainable
let myMap = new Map() let keyObj = {} myMap.set(keyObj, Mymap. get({}) // undefined mymap. get(NaN); ForEach (function(value, key) {console.log(key + "=" + value); })Copy the code

Map and array relationship

In the form of a two-dimensional array

let arr = [[key, value], [xiaoming, 12] let aMap = new Map(arr) let arr2 = [...aMap] console.log(array. from(amap.keys)) The one behind will cover the one in front. let merged = new Map([...arr, ...xxx, [1, 'eins']]);Copy the code

Value overrides are done through map.set.

Attention! Do not set object properties for Map, use set instead. Or there will be an accident. let wrongMap = new Map() wrongMap[‘bla’] = ‘blaa’

3. WeakSet can only be a collection of objects, not any value of any type and cannot be enumerated

The reference of the object in the WeakSet object set is weak reference, which will not be marked reference and is easy to be garbage collected.

This parameter is used when multiple objects are involved.

Garbage Collection cases:

let obj = {name : 'HHH '} // Let array = [obj] is not garbage collected // let map = new WeakMap() map.set(obj,' Because it is a weak reference ') obj = null // can be recycledCopy the code

ECMAScript 6: what is WeakSet for?

Case study:

Case 1: We can add users to WeakSet to track users who have visited our website

let visitedSet = new WeakSet(); let john = { name: "John" }; let pete = { name: "Pete" }; let mary = { name: "Mary" }; visitedSet.add(john); // John visits visitedSet.add(Pete); // Then Pete visitedset.add (John); // visitedSet now has two users // Check whether John has visited. alert(visitedSet.has(john)); // true // Check if Mary called. alert(visitedSet.has(mary)); // false john = null; // visitedSet will be automatically cleanedCopy the code

Case 2,

const requests = new WeakSet(); class ApiRequest { constructor() { requests.add(this); } makeRequest() { if(! request.has(this)) throw new Error("Invalid access"); // Do work}} // If there is no weakSet, you may need to manage through the lifecycle, manually deleting const requests = new Set(); class ApiRequest { constructor() { requests.add(this); } makeRequest() { if(! request.has(this)) throw new Error("Invalid access"); // do work } destory(){ requests.delete(this) } }Copy the code

The ApiRequest class wants to verify the origin of this object, so it needs a collection to hold all the objects built by the constructor. The ApiRequest class does not want to participate in the life cycle of the instance object. Using Set directly causes memory leaks because it has references to the instance object.

Case 3, DOM node as key name

Consturctor API

4. WeakMap key must be an object and cannot be enumerated

A WeakMap object is a set of key/value pairs where the keys are weakly referenced. The key must be an object, and the value can be arbitrary. Map assignments and searches are O(n) and are prone to memory leaks because arrays reference every key and value all the time.

Basically, if you want to add data to an object, that is, the storage of extra data without interfering with garbage collection, you can use WeakMap.

Used to store the data associated with this object, and co-exist with the data:

  • Case 1: a user object is the key, and the number of accesses is the value. When a user leaves (the user object will be collected by the garbage collection mechanism), we no longer need his number of visits
Let visitsCountMap = new WeakMap () / / number of recursive users visiting the function countUser (user) {let count = visitsCountMap. Get (user) | | 0 Visitscountmap. set(user, count + 1)} // 📁 main.js let John = {name: "John"}; countUser(john); // count his visits // after a while, John left John = null;Copy the code
  • Case 2. Result of cache calculation
Let cache = new WeakMap() function process(obj){if(! Cache.has (obj)) {let result = 'cache.set(obj, result) } return cache.get(obj) } // other.js let obj = {} let result1 = process(obj) let result2 = process(obj) obj = Null // If it is Map, the cache cannot be reclaimedCopy the code

Case 3, DOM node as key name

Consturctor API

The small hui:

  • A Set is like an array, with unique member values.
  • WeakSet is similar to Set, but its members can only be objects, and there is no traversal operation. It is automatically reclaimed if it is not referenced.
  • A Map is similar to an object. The key value is not limited to strings, but the member value is unique.
  • WeakMap is similar to Map, but only accepts objects as key names (except null) and does not iterate. Unreferenced will be recycled.

Map and WeakMap are understood through garbage collection mechanism

MDN