ES6 adds two new data structures, a set and a map.

1, set

As defined in JavaScript you Didn’t know (Volume 2), a set is a collection of values whose values are unique (duplicates are ignored). It is similar to an array, but the value of each member is unique. Set is a constructor that can be used to create an instance of a set using new.

let set = new Set([1, 2, 3, 1, 4]);
console.log(set); / / {1.2.3.4}
Copy the code

As you can see, the new Set automatically filters out duplicates and returns a collection. We can use this feature to write simple array deduplicates.

let set = new Set([1, 2, 3, 1, 4]);
let arr = [...set];
console.log(arr); // [1, 2, 3, 4]
Copy the code

The set adds members by adding (), placing new values at the end of the set, and automatically filtering out new values that repeat members of the set.

let set = new Set([1, 2, 3, 1, 4]);
set.add(1);
console.log(set); / / {1.2.3.4}
let set = new Set([1, 2, 3, 1, 4]);
set.add(0);
console.log(set); / / {1.2.3.4.0} Copy the code

The constructor for Set can take an additional data structure with an Iterable interface as an argument.

// 例1
let set = new Set("string");
console.log(set); / / {"s"."t"."r"."i"."n"."g"}
// 例2
function foo(a, b) {
 let set = new Set(arguments);  console.log(set); / / {1.2} } foo(1.2); Copy the code

2. Set API

Set has two instance properties:

  1. Set. The prototype. The constructor: constructor, the default is Set function.
  2. Set.prototype.size: Returns the number of values in a Set.

Instance methods are divided into two classes, an operation class and a traversal class. Operation:

  1. Set.prototype.add(value) : Adds an element to the end of the Set. Returns the Set object.
  2. Set.prototype.clear() : Removes all elements from a Set.
  3. Set.prototype.delete(value) : Removes an element from a Set that is equal to this value, returning the value that set.prototype.has (value) returned before the operation (true if the element exists, false otherwise). Set.prototype.has(value) returns false after that.
  4. Set.prototype.has(value) : Returns a Boolean value indicating whether the value exists in the Set.
// 例1
let set = new Set([1, 2, 3]);
set.clear();
console.log(set); / / {}// 例2
let set = new Set([1, 2, 3]); let result = set.delete(1); console.log(result); // true console.log(set); / / {2.3} // 例3 let set = new Set([1, 2, 3]); let result = set.has(1); console.log(result); // true Copy the code

Traversal classes:

  1. Set.prototype.values() : Returns a new iterator containing the values of all elements in the Set in the order they were inserted.
  2. Set.prototype.keys() : As in values(), returns a new iterator containing the values of all the elements in the Set in the order they were inserted.
  3. Set.prototype.forEach(callbackFn[, thisArg]) : call callbackFn once forEach value in the Set, in the insertion order. If thisArg is provided, this will be the argument in the callback.
  4. Set.prototype.entries() : Returns a new iterator object containing the [value, value] array of the values of all the elements in the Set in insertion order. To keep the method similar to the Map object, the key and value of each value are equal.
// 例1
let set = new Set([1, 2, 3]);
let keys = set.keys();
console.log(keys); / / {1.2.3}
// 例2
let set = new Set([1, 2, 3]); let values = set.values(); console.log(values); / / {1.2.3} Copy the code

In both examples, since Sset has no key name, only a value, the results for keys and values are the same. Set also has a forEach method:

let set = new Set([1, 2, 3]);
set.forEach((key, value) => {
  console.log(`${key}:${value}`);
});
/ / 1:1
/ / 2:2 / / 3-3 Copy the code

Unlike the array forEach method, its callback takes its key and value as arguments, but the Set has no key, so its key and value are equal. The second argument to forEach is the this value, which is bound to the this value in the callback function. The final instance method is Entries:

let set = new Set([1, 2, 3]);
let entries = set.entries();
console.log(entries);
/ / {/ / [1, 1),
/ / (2, 2], / / [3, 3] // } Copy the code

Enteries () returns a iterator that returns an equal key-value pair.

3, WeakSet

WeakSet is also a constructor, and Set has been, WeakSet and Set are similar but different, the main differences are two:

  1. A member value of a WeakSet must be an object (an iterable object), not a value of a native type like a set.
  2. WeakSet holds weak reference: The references of objects in the collection are weak references. If there are no other references to the objects in the WeakSet, those objects will be garbage collected. This also means that there is no list of current objects stored in the WeakSet. Because of this, WeakSet is not enumerable.
let weakSet = new WeakSet([1.2]); // Uncaught TypeError: Invalid value used in weak set
let weakSet = new WeakSet([
  [1.2].  [3.4].]); // {[1, 2], [3, 4]}
Copy the code

WeakSet has three instance methods:

  1. Weakset.prototype. add(value) : Returns the constructor, which is WeakSet itself.
  2. Weakset.prototype.delete (value) : The value element is deleted from the WeakSet object, after which the weakset.prototype.has (value) method returns false.
  3. Weakset.prototype. has(value) : Returns a Boolean value indicating whether the given value exists in the WeakSet.
var ws = new WeakSet(a);var foo = {};
var bar = {};

ws.add(foo);
ws.add(bar);  ws.has(foo); // true ws.has(bar); // true  ws.delete(foo); // Delete foo from the set ws.has(foo); // false, the foo object has been deleted ws.has(bar); // True, bar still exists Copy the code

4, the Map

In JS, objects are the primary mechanism for creating unordered key/value pair data structures (also known as maps). However, the main disadvantage of objects as mappings is that you cannot use non-string values as keys. So in ES6, we propose a new data structure, Map. A Map is similar to an object in that it takes the form of a key-value pair, but the key of a Map can be of any type (object or raw value), and NaN can also be used as a key, not just a string. Any data structure with an Iterator interface where each member is a two-element array can be used as an argument to the Map constructor.

let map = new Map([[{a:1},3]]);
console.log(map);//{ { a:1 },3}
Copy the code

MDN clearly lists the differences between Map and Object:

Map Object
The accident of key Map does not contain any keys by default. Contains only explicitly inserted keys. An Object has a prototype. The key names on the prototype chain may conflict with the key names you set on the Object. Note: Although ES5 can initially use object.create (null) to create an Object without a stereotype, this usage is less common.
The type of the key The key of a Map can be any value, including a function, an object, or any basic type. The key of an Object must be a String or Symbol.
The order of the keys Keys in a Map are ordered. Thus, when iterating, a Map object returns the keys in the order in which they were inserted. The key of an Object is unordered. Note: Since the ECMAScript 2015 specification, objects do retain the order in which strings and Symbol keys are created; Therefore, iterating over an object that only has string keys produces keys in insertion order.
Size The number of key-value pairs for a Map can be easily obtained by the size attribute The number of Object key-value pairs can only be calculated manually
The iteration The Map is iterable, so it can be iterated directly. Iterating over an Object requires obtaining its key in some way before iterating over it.
performance It performs better in scenarios where key-value pairs are frequently added and deleted. Not optimized for scenarios where key-value pairs are frequently added and deleted.

5. Map API

There are two instance properties of a Map:

  1. The Map. The prototype. The constructor: return a function, it created the prototype of the instance. The default is the Map function.
  2. Map.prototype.size: Returns the number of key/value pairs of the Map object.

Instance methods are divided into two classes, an operation class and a traversal class. Operation:

  1. Map.prototype.set(key, value) : Sets the key value of the Map object. Return the Map object.
  2. Map.prototype.get(key) : Returns the value of the key, or undefined if it does not exist.
  3. Map.prototype.has(key) : Returns a Boolean value indicating whether the Map instance contains the value corresponding to the key.
  4. Map.prototype.delete(key) : If this element exists in the Map object, remove it and return true; Otherwise return false if the element does not exist. A subsequent call to map.prototype.has (key) will return false.
  5. Map.prototype.clear() : Removes all key/value pairs from a Map object.
let map = new Map(a);let key = {name:"Jack"};
let value = "What";
map.set(key, value); //{{name:'Jack'}:' what '}
map.get(key); / / 'what'
map.get(a); // undefined map.has(key); // true map.delete(key); // true map.clear(); / / {} Copy the code

Traversal classes:

  1. Map.prototype.entries() : Return a new Iterator containing the [keys, values] array of each element in the Map, in insertion order.
  2. Map.prototype.forEach(callbackFn[, thisArg]) : call the callbackFn function once forEach key-value pair in the Map object in the insertion order. If thisArg is provided for forEach, it will be used as the this value in each callback.
  3. Map.prototype.keys() : returns a new Iterator containing the keys of each element in the Map in the order it was inserted.
  4. Map.prototype.values() : Returns a new Iterator containing the values of each element in the Map in the order it was inserted.
let map = new Map([
  ["name"."Jack"].  [{age:25},"What"].]);
map.entries(); MapIterator {"name"=>"Jack",{age:25}=>" what "}
for (let item of map.entries()) {  console.log(item); ["name","Jack"] [{age:25}," what "] } map.forEach((value, key, map) = > {  console.log(value, key, map); / / Jack name Map (2) {" name "= >" Jack ", {age: 25} = > "what"}  / / "what" {age: 25} Map (2) {" name "= >" Jack ", {age: 25} = > "what"} }); map.keys(); // MapIterator {"name",{age:25}} for (let item of map.keys()) {  console.log(item); // "name" {age:25} } map.values(); MapIterator {"Jack"," what "} for (let item of map.values()) {  console.log(item); // "Jack" "What" } Copy the code

6. Map and other data structure transformations

6.1 Transfer Map to array

ES6 gives one of the simplest ways to extend operators.

let map = new Map([
  ["name"."Jack"].  [{ age: 25 }, "What"].]);
console.log([...map]); // [['name', 'Jack'], [{age: 25}, 'what ']]
Copy the code

You can also use array.from ().

let map = new Map([
  ["name"."Jack"].  [{ age: 25 }, "What"].]);
console.log(Array.from(map)); // [['name', 'Jack'], [{age: 25}, 'what ']]
Copy the code

6.2 Transfer objects from Map

If all Map keys are strings, it can be converted to objects lossless.

function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k, v] of strMap) {
    obj[k] = v;
  }
 return obj; }  const myMap = new Map().set("yes".true).set("no".false); strMapToObj(myMap); // { yes: true, no: false } Copy the code

6.3 turn the Map JSON

There are two forms of Map to JSON. The first is when the key names are both string types, and the second is when the key names contain non-string types. In the first case, convert the map directly to an object and then convert it using json.stringfy (). The second can be converted to array JSON.

function mapToArrayJson(map) {
  return JSON.stringify([...map]);
}

let myMap = new Map().set(true.7).set({ foo: 3},"abc"]);
mapToArrayJson(myMap); // '[[true,7],[{"foo":3},["abc"]]]' Copy the code

7, WeakMap

A WeakMap is similar to a WeakSet in that it is a weak reference and the key of the member value must be an object.

let weakMap = new WeakMap([[1.3]]); // Uncaught TypeError: Invalid value used as weak map key
let weakMap = new WeakMap([[{name:"Jack"},3]]); // {{name:'Jack'}:3}
Copy the code

WeakMap has four instance methods:

  1. Weakmap.prototype. delete(key) : Removes the associated object of key. Weakmap.prototype. has(key) returns false after execution.
  2. Weakmap.prototype. get(key) : Returns the key associated object, or undefined(when there is no key associated object).
  3. Weakmap.prototype. has(key) : Returns a Boolean value based on whether there is a key associated object.
  4. Weakmap.prototype. set(key, value) : Sets a group of key associated objects in a WeakMap and returns the WeakMap object.
let weakMap = new WeakMap(a);let obj = {name: 'Jack'};
weakMap.set(obj, 3); // {{name:'Jack'}: 3}
weakMap.get(obj); / / 3
weakMap.has(obj); // true
weakMap.delete(obj); // true Copy the code

8. Map application

The most direct application of Map is the policy mode. For example, if a company’s year-end bonus is the first prize is computer, the second prize is mobile phone, the third prize is step by step high reading machine, the fourth prize is mineral water. It usually goes something like this:

function getAnnualBonus(level) {
  if (level === "First prize") {
    return "Computer";
  } else if (level === "Second prize") {
    return "Mobile phone";
 } else if (level === "Third prize") {  return "Step by step, read the machine.";  } else if (level === "Fourth prize") {  return "Mineral water";  } } getAnnualBonus("First prize"); / / or function getAnnualBonus(level) {  switch (level) {  case "First prize":  return "Computer";  case "Second prize":  return "Mobile phone";  case "Third prize":  return "Step by step, read the machine.";  case "Fourth prize":  return "Mineral water";  default:  break;  } } getAnnualBonus("First prize"); Copy the code

In both cases, if there are more and more conditions, then if… else… And cases are getting longer and longer, and the code is pretty bloated. Use Map to write strategy pattern, concise and clear:

let annualBonus = new Map([
  ['First Prize'.'computer'].  ['Second prize'.'mobile phone'].  ['Third prize'.'Step by step higher reader'].  ['Fourth prize'.'Mineral water']
]); function getAnnualBonus(level) {  return annualBonus.get(level); } getAnnualBonus("First prize"); Copy the code

Reference:

Set and Map data structures

After the language

Related articles:

  • Take you relearn ES6 | var, let and the difference between const
  • Take you relearn ES6 | Promsie
  • Take you relearn ES6 | Generator
  • Take you relearn ES6 | Async and Await
  • Take you relearn ES6 | Set and Map
  • Take you relearn ES6 | Symbol (more than just a new data type)
  • Take you relearn ES6 | Exprort (keep in mind that the output is variable)
  • Take you relearn ES6 | proxy and defineProperty)

    I think it’s ok, please give me a thumbs-up when I go, so that more people can see this article, and we can study and discuss together! Don’t point like of all is play rascal 😂

    You can also follow my blog and hope to give me a Start on Github, you will find a problem, almost all my user names are related to tomatoes, because I really like tomatoes ❤️!!

    The guy who wants to follow the car without getting lost also hopes to follow the public account or scan the qr code below 👇👇👇.

    I am a primary school student in the field of programming, your encouragement is the motivation for me to keep moving forward, 😄 hope to refueling together.

    This article was typeset using MDNICE