Heavy learning JavaScriptThe purpose of the article is to review the basis, convenient learning framework and source code when you can quickly locate knowledge points, check loopholes to fill gaps, all articles are synchronized inPublic number (front stack in road)githubOn.

Map

Before ECMAScript6, the JavaScript implementation of “key/value” storage can be efficiently implemented using Object, that is, the property of the Object as the key, the value of the property as the value. But this implementation was not without its problems, so the TC39 committee defined a specification specifically for “key/value” storage.

Map is a new collection type that brings true key-value storage to JavaScript. Most of the features in maps can be implemented with Object, but there are some subtle differences.

API

The Map constructor creates an empty Map using the new operator:

const m = new Map(a);Copy the code

If you want to initialize the instance while creating it, you can pass in an iterable containing an array of key-value pairs:

const m = new Map([["key"."value"]]); m.size/ / 1
Copy the code

After initialization, you can add key-value pairs using the set() method, query with get() and has(), get the number of key-value pairs using the size attribute, and delete() and clear() to delete values.

const m = new Map(a); m.has("name"); // false
m.get("name"); // undefined

m.set("name"."abc")
 .set("age".12);

m.has("name"); // true
m.get("name"); // "abc"
m.size / / 2

m.delete("name");
a.size / / 1

m.clear();
m.size / / 0
Copy the code

Because the set method returns a mapping instance, you can use. To do the chain operation.

In Object, keys can only use numbers, strings, and symbols, but in Map you can use any JavaScript data type as a key, and there is no limit to how many values it maps to.

const m = new Map(a);const fnKey = () = > {};
const symbolKey = () = > {};
const objKey = () = > {};

m.set(fnKey, "fnValue")
 .set(symbolKey, "symbolValue")
 .set(objKey, "objValue");

m.get(fnKey); //fnValue
m.get(symbolKey); //symbolValue
m.get(objKey); // objValue
Copy the code

Objects and other “collection” types that are used as keys and values in a map remain unchanged when their own content or attributes are modified.

const m = new Map(a);const objKey = {}, 
 objVal = {}, 
 arrKey = [], 
 arrVal = []; 
m.set(objKey, objVal); 
m.set(arrKey, arrVal); 

objKey.foo = "foo"; 
objVal.bar = "bar"; 
arrKey.push("foo"); 
arrVal.push("bar"); 

console.log(m.get(objKey)); // {bar: "bar"} 
console.log(m.get(arrKey)); // ["bar"]
Copy the code

Sequence and iteration

One major difference from Object is that there is no insertion order in Object, whereas Map maintains the insertion order of key-value pairs so that iterating operations can be performed based on the insertion order.

An instance of the map provides an Iterator that can generate arrays of the form [key, value] in insertion order, which can be obtained through the entries() method (or the symbol.iterator property, since it references entries) :

const m = new Map([["k"."val"]]); m.entries === m[Symbol.iterator]; // true

for (let c of m.entries()){
  console.log(c);
};
// ["k", "val"]
Copy the code

Since entries() are the default iterator, you can extend maps directly to turn them into arrays:

[...m] // [["k", "val"]]
Copy the code

Of course, you can also use methods like forEach.

Keys () and values() return iterators that generate key values in insertion order, respectively:

for (let key of m.keys()) { 
 console.log(key)
}
// k

for (let value of m.values()) { 
 console.log(value)
}
// val
Copy the code

Note: In a Map, key values can be changed during traversal, but references within the Map cannot be changed

const m = new Map([["k"."val"]]);for(let key of m.keys()){
  key = "newK";
  console.log(key, m.get("k"));
};
console.log(m.entries());
// newK val
// MapIterator {"k" => "val"}

for(let key of m.values()){
  key = "newV";
  console.log(key, m.get("k"));
};
console.log(m.entries());
// newV val
// MapIterator {"k" => "val"}
Copy the code

WeakMap

WeakMap is a new collection type added in ECMAScript6. It is a sibling of Map and its API is also a subset of Map. Weak in WeakMap describes how JavaScript garbage collection treats the keys in weak Map.

API

Instantiate an empty WeakMap using the new keyword:

const wm = new WeakMap(a);Copy the code

In weak mappings, the key can only be Object or a type inherited from Object. TypeError is reported if any other type is used. There is no restriction on the type of the value.

const key = {id: 1}
const wm = new WeakMap([
  [key, "value"]]); wm.get(key);// "value"
Copy the code

After initialization, key-value pairs can be added using set(), queried using get() and has(), and deleted using delete() :

const wm = new WeakMap(a);const key1 = {id: 1}, 
 key2 = {id: 2}; 
wm.has(key1); // false 
wm.get(key1); // undefined 

wm.set(key1, "Matt") 
  .set(key2, "Frisbie"); 
wm.has(key1); // true 
wm.get(key1); // Matt 

wm.delete(key1); // Delete only one key/value pair
wm.has(key1); // false 
wm.has(key2); // true
Copy the code

Objects that WeakMap keys point to are not included in the garbage collection mechanism.

So why design a WeakMap? Here’s an example from Ruan Yifeng:

const e1 = document.getElementById('foo');
const e2 = document.getElementById('bar');
const arr = [
  [e1, 'foo elements'],
  [e2, 'the bar elements']];Copy the code

In the above code, e1 and e2 are two objects, which are specified by arR. At this point, ARR refers to E1 and e2. Once these objects are no longer needed, the reference must be removed manually, otherwise the garbage collection mechanism will not release E1 and E2:

arr[0] = null;
arr[1] = null;
Copy the code

It’s easy to forget this notation, causing memory leaks.

WeakMap is born to solve this problem. The objects referenced by its key name are weak references, and the garbage collection mechanism will not consider them. As long as the referenced object is removed, the garbage collection mechanism will release the memory occupied by the object, without us manually deleting the reference.

WeakMap’s special case is that the object to which its key corresponds may disappear in the future. WeakMap helps prevent memory leaks.

Note: The weak reference in the map is the key name, and the key value is still a normal reference.

const wm = new WeakMap(a);let key = {};
let obj = {foo: 1};

wm.set(key, obj);
obj = null;
wm.get(key)
// Object {foo: 1}
Copy the code

Select Object or Map

For memory and performance, there are some general differences:

  1. Memory footprint

    When given a fixed size of memory by the browser, Map stores 50% more key-value pairs than Object.

  2. Insert performance

    In insert scenarios, Map is faster than Object. If a large number of insert operations are involved, Map is preferred.

  3. To find the speed

    Object and Map have little difference in search speed. If there are a small number of key-value pairs, use Object

  4. Delete the performance

    In general, the delete operation is not very common. It is usually assigned to undefined or NULL. If there are a lot of delete operations, the Map delete operation is much faster

Set

Sets can be thought of as enhanced maps whose apis and behaviors are mostly common.

API

Set is also created with the new keyword:

const m = new Set(a);Copy the code

The parameter passed to initialize is also an iterable, including elements inserted into the new collection instance:

const s = new Set(["foo"."bar"]);
s.size / / 3
Copy the code

After initialization, you can add values using add(), query with has(), get the number of elements using size, and delete elements using delete() and clear() :

const s = new Set(a); s.has("name"); // false
s.size; / / 0

s.add("name")
 .add("age");
s.has("name"); // true
s.size; / / 2

s.delete("name");
s.has("name"); //false

s.clear();
s.size; / / 0
Copy the code

The add above is like the set method in a Map. A Set can contain any JavaScript data type as a value:

const s = new Set(a);const functionVal = () = > {}; 
const symbolVal = Symbol(a);const objectVal = new Object(a); s.add(functionVal); s.add(symbolVal); s.add(objectVal); s.has(functionVal);// true 
s.has(symbolVal); // true 
s.has(objectVal); // true 
Copy the code

Similarly, objects used as values and other “collection” types do not change when their contents or properties are modified:

const s = new Set(a);const objVal = {}, 
 arrVal = []; 

s.add(objVal); 
s.add(arrVal); 

objVal.bar = "bar"; 
arrVal.push("bar"); 

s.has(objVal); // true 
s.has(arrVal); // true
Copy the code

The delete method on Set returns a Boolean value indicating whether the Set has a value to delete:

const s = new Set(a); s.add('foo'); 
s.size; / / 1
s.add('foo'); 
s.size; / / 1

// The set has this value
s.delete('foo'); // true 
// Set does not have this value
s.delete('foo'); // false
Copy the code

The iteration

The iteration of a Set is similar to that of a Map, but it can also be extended directly to a collection instance:

const s = new Set(["foo"."bar"]);
[...s] // ["foo", "bar"]
Copy the code

Other uses for iterators are the same as for maps.

WeakSet

WeakSet is the sibling type of Set, which is a WeakSet. Its usage is similar to Set and WeakMap.

The value must be Object or a type inherited from Object, otherwise TypeError will be reported.

const val1 = {id: 1}, 
 val2 = {id: 2}, 
 val3 = {id: 3};
const ws = new WeakSet([val1, val2, val3]);
ws.has(val1); // true
ws.has(val2); // true
ws.has(val3); // true
Copy the code

It also supports add, HAS, and delete, which are used in the same way as Set.

In terms of garbage collection, it is the same as WeakMap.

conclusion

Set and Map are mainly used in data reorganization and storage.

  • Set

    • Internally, it is similar to an array, with unique and unordered members
    • [value, value], a key, is the same as a key name
    • You can iterate, add, delete, has, clear
  • WeakSet

    • Members are objects
    • Members are weak references that can be collected by the garbage collection mechanism and can be used to save the DOM
    • Cannot traverse, methods are add, delete, has, clear
  • Map

    • It’s essentially a set of key-value pairs, sort of a set, [key, value]
    • It can be traversed by methods like get, set, has, delete, and clear
  • WeakMap

    • Only accept objects as key names (except null)
    • The key name is a weak reference, and the key value is arbitrary. The object that the key name points to can be garbage collected
    • The methods are get, set, has, delete, clear*

My public number: the front end stack in the road, a front end article every day, the feeling of chewing is wonderful ~