“This is the fifth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

Reading notes fourth article series, this paper mainly summarizes the fifth, six chapters, the content of the basic reference collection types and reference types, in which the fundamental reference types can be summed up much, mainly is the use of some methods, I list here the link to set a reference type made about introduction, on specific concept of the later chapters and learning. At present, the reading notes may be too personal, and THERE are many places where I think I have not made detailed records. I will keep improving the reading notes when I sort them out later, and I hope I can sort them out perfectly and easily. Come on 💪🏻

Reference types

Basic reference types

Date

RegExp

Raw value wrapper type

Boolean

  1. Boolean.prototype.toString()
  2. Boolean.prototype.valueOf()

Number

  1. Properties

    1. Number.EPSILON
    2. Number.MAX_SAFE_INTEGER
    3. Number.MAX_VALUE
    4. Number.MIN_SAFE_INTEGER
    5. Number.MIN_VALUE
    6. Number.NaN
    7. Number.NEGATIVE_INFINITY
    8. Number.POSITIVE_INFINITY
  2. Methods

    1. Number.isFinite()
    2. Number.isInteger()
    3. Number.isNaN()
    4. Number.isSafeInteger()
    5. Number.parseFloat()
    6. Number.parseInt()
    7. Number.prototype.toExponential()
    8. Number.prototype.toFixed()
    9. Number.prototype.toLocaleString()
    10. Number.prototype.toPrecision()
    11. Number.prototype.toString()
    12. Number.prototype.valueOf()

String

  1. Properties

    1. String length
  2. Methods

    1. String.prototype[@@iterator]()
    2. String.prototype.at()
    3. String.prototype.charAt()
    4. String.prototype.charCodeAt()
    5. String.prototype.codePointAt()
    6. String.prototype.concat()
    7. String.prototype.endsWith()
    8. String.fromCharCode()
    9. String.fromCodePoint()
    10. String.prototype.includes()
    11. String.prototype.indexOf()
    12. String.prototype.lastIndexOf()
    13. String.prototype.localeCompare()
    14. String.prototype.match()
    15. String.prototype.matchAll()
    16. String.prototype.normalize()
    17. String.prototype.padEnd()
    18. String.prototype.padStart()
    19. String.raw()
    20. String.prototype.repeat()
    21. String.prototype.replace()
    22. String.prototype.replaceAll()
    23. String.prototype.search()
    24. String.prototype.slice()
    25. String.prototype.split()
    26. String.prototype.startsWith()
    27. String.prototype.substring()
    28. String.prototype.toLocaleLowerCase()
    29. String.prototype.toLocaleUpperCase()
    30. String.prototype.toLowerCase()
    31. String.prototype.toString()
    32. String.prototype.toUpperCase()
    33. String.prototype.trim()
    34. String.prototype.trimEnd()
    35. String.prototype.trimStart()
    36. String.prototype.valueOf()

Singleton built-in object

Global

  1. encodeURI() && encodeURIComponent()
  2. decodeURI() && decodeURIComponent()
  3. eval()When the interpreter finds an eval() call, it interprets the arguments as actual ECMAScript statements and inserts them into that location. The code executed through eval() belongs to the context of the call, and the code executed has the same scope chain as that context. This means that variables defined in the containment context can be referenced inside an eval() call.
 let msg = "hello world";
 
  eval("console.log(msg)");// "hello world"
 
 eval("function sayHi() { console.log('hi'); }");
 sayHi(); // "hi"
Copy the code

Any variables and functions defined by eval() are not promoted because they are contained in a string when parsing code. They are created only when eval() is executed. In strict mode, variables and functions created inside eval() cannot be accessed externally. In other words, the last two examples will report an error. Similarly, in strict mode, assigning to eval results in an error:

"use strict"; 
eval = "hi";// Cause an error
Copy the code
  1. Global Object properties (undefined, Array, Object, RexExp, TypeError,…)

Math

  • Rounding method

    • The math.ceil () method always rounds up to the nearest integer.
    • The math.floor () method always rounds down to the nearest integer.
    • The math.round () method performs rounding.
    • The math.fround () method returns the closest single-precision (32-bit) floating-point representation of the value.
  • random() : [0, 1)

  • Other calculation methods

Collection reference type

Object

Term memory

  • Object literals -> expression context
  • Expression Context: In ECMAScript, an expression context is the context in which a value is expected to be returned.
  • Statement context: eg: after the condition of the if statement

Array

Static methods are added in ES6

  • Array.from() is used to convert a class Array structure into an Array instance
  • Array.of() is used to convert a set of parameters to an Array instance. ES6 before using Array. Prototype. Slice. The call (the arguments) to implement the conversion parameters to the Array, you can now use an Array, of (the arguments) instead

An array of space

When you initialize an array with an array literal, you can use a string of commas to create a hole.

ECMAScript treats the values of the corresponding index positions between commas as empty Spaces, and the ES6 specification redefines how to handle these empty Spaces.

const options = [,,,,,]; // Create an array of 5 elements
console.log(options.length); / / 5
console.log(options); / / /,,,,,,,The new methods and iterators in ES6 differ from the method behavior that existed in earlier versions of ECMAScript. The ES6 new methods generally treat these empty Spaces as existing elements with a value ofundefined:const options = [1.5];

for (const option of options) { console.log(option === undefined); } 
// false // true // true // true // falseMethods prior to ES6 ignored this void, but the behavior varies from method to method:const options = [1.5];

// Map () skips empty positions
console.log(options.map(() = > 6)); // [6, undefined, undefined, undefined, 6]
// join() treats empty positions as empty strings
console.log(options.join(The '-'));
1-5 "/ /"Because of inconsistent behavior and potential performance concerns, array vacancies are avoided in practice. If you really need a vacancy, you can use it explicitlyundefinedValue instead.Copy the code

Detection array

Array.isArray()

Iterator method

Keys (), values(), entries()

Copy and fill methods

New method in ES6

copyWithin(target, ? start, ? End): batch replication method

fill(value, ? start, ? End): Fills the array method

The function signature of both methods is similar in that you need to specify a range on the existing array instance, with the start index and no end index. Using this method does not change the size of the array.

Fill () silently ignores index ranges beyond array boundaries, zero length, and in opposite directions:const zeroes = [0.0.0.0.0];
// Index too low, ignored
zeroes.fill(1, -10, -6); 
console.log(zeroes); // [0, 0, 0, 0, 0]

// Index is too high, ignored
zeroes.fill(1.10.15);
console.log(zeroes); // [0, 0, 0, 0, 0]
// Index reversed, ignored
zeroes.fill(2.4.2); 
console.log(zeroes);
// [0, 0, 0, 0, 0]

// Index section is available, populate the available section
zeroes.fill(4.3.10) 
console.log(zeroes); 
// [0, 0, 0, 4, 4]
Copy the code

Conversion method

  • ToLocaleString () : Calls item.tolocaleString, the resulting string
  • ToString () // Returns a comma-separated string joined by the equivalent string of each value in the array (call item.tostring ()).
  • ValueOf () // Returns the array itself.

The stack method

The stack is a LIFO (last-in-first-out) structure.

Data push(element0, element1… , elementN): The new length property of the object upon which the method was called.)

(pop():The removed element from The array; undefined if the array is empty.)

Queue method

Queues restrict access on a first-in, first-out (FIFO) basis.

(Shift () : The shift() method removed element from the array; undefined if the array is empty.)

Queue push()

Sorting method

reverse():The reversed array.

sort(? compareFunction(firstEl, secondEl)):the sorted array. Note that the array is sorted in place, And no copy is made. (return value > 0 secondEl before firstEl, value < 0 firstEl before secondEl, 0 does not switch positions)

Operation method

concat(? value0, value1, … , valueN):A new Array instance.concat () adds each item of these arrays to the result Array. If the parameters are not arrays, they are appended directly to the end of the result array.

slice(? start, ? end): A new array containing the extracted elements.

Splice (start? DeleteCount,? item1, item2, itemN):An array containing the deleted elements.

Search and location methods

ECMAScript provides two types of methods for searching arrays: by strict equality and by assertion functions.

Strictly equal

  • indexOf(searchElement, ? fromIndex):The first index of the element in the array; -1 if not found.
  • lastIndexOf(searchElement, ? fromIndex):The last index of the element in the array; -1 if not found.
  • includes(searchElement, ? fromIndex):A boolean value which is true if the value searchElement is found within the array (or the part of the array indicated by the index fromIndex, if specified).

Assertion functions

  • find(callbackFn(el, ? index, array), ? thisArg):The value of the first element in the array that satisfies the provided testing function. Otherwise, undefined is returned.
  • findIndex(callbackFn(el, ? index, array), ? thisArg):The index of the first element in the array that passes the test. Otherwise, -1.

An iterative approach

  • every()This method runs the passed function on each entry in the array, and returns true if it returns true for each entry.
  • filter()The function passed in to each item of the array is run. Items that return true are returned as arrays.
  • forEach()The passed function is run on each item of the array, with no return value.
  • map()The passed function is run on each item of the array, returning an array of the results of each function call.
  • some()This method runs the passed function on each item of the array, returning true if one of the functions returns true. None of these methods change the array from which they are called.

Merge method

  • reduce(callbackFn(accumulator, currentValue, ? index, array), ? initialValue): The value that results from the reduction
  • reduceRight()

Stereotype array: TODO

Typed arrays are new ECMAScript constructs designed to increase the efficiency of transferring data to native libraries. In fact, JavaScript does not have a “TypedArray” type; instead, it refers to a special array that contains numeric types.

Mozilla has implemented CanvasFloatArray to solve this problem of passing WebGL native and js arrays. This is a C-style array of floating-point values that provides a JavaScript interface. JavaScript runtime uses this type to allocate, read, and write arrays. This array can be passed directly to or retrieved from the underlying graphics driver API. Eventually, CanvasFloatArray became Float32Array, which is the first “type” available in stereotype arrays today.

ArrayBuffer

Float32Array is actually a “view” that allows the JavaScript runtime to access a piece of pre-allocated memory called an ArrayBuffer. An ArrayBuffer is the base unit for all stereotype array and view references.

// ArrayBuffer() is a common JavaScript constructor that can be used to allocate a specific amount of byte space in memory.
const buf = new ArrayBuffer(16); // Allocate 16 bytes in memory
alert(buf.byteLength); / / 16
// ArrayBuffer cannot be resized once created. However, you can copy all or part of it into a new instance using slice() :
const buf1 = new ArrayBuffer(16); 
const buf2 = buf1.slice(4.12); 
alert(buf2.byteLength); / / 8
Copy the code

ArrayBuffer is somewhat similar to C++ ‘s malloc(), but with a few notable differences. / / 6.3.2

DataView: TODO

The first view that allows you to read and write an ArrayBuffer is the DataView. This view is designed for file I/O and network I/O, and its API supports a high degree of control over buffered data, but also has poor performance compared to other types of views. DataView has no presets for buffered content and cannot iterate.

You cannot create a DataView instance unless you are reading or writing to an existing ArrayBuffer. This instance can use all or part of the ArrayBuffer, and maintains a reference to the buffer instance, as well as the view’s starting position in the buffer.

const buf = new ArrayBuffer(16);

DataView uses the entire ArrayBuffer by default
const fullDataView = new DataView(buf); 
alert(fullDataView.byteOffset); / / 0
alert(fullDataView.byteLength); / / 16
alert(fullDataView.buffer === buf); // true

// The constructor accepts an optional byte offset and byte length

// byteOffset=0 indicates that the view starts from the buffer

// byteLength=8 Limits the view to the first 8 bytes
const firstHalfDataView = new DataView(buf, 0.8); 
alert(firstHalfDataView.byteOffset); / / 0
alert(firstHalfDataView.byteLength); / / 8
alert(firstHalfDataView.buffer === buf); // true

// If not specified, the DataView will use the remaining buffer
// byteOffset=8 indicates that the view starts from the 9th byte of the buffer
// byteLength is not specified, default is residual buffer
const secondHalfDataView = new DataView(buf, 8);
alert(secondHalfDataView.byteOffset); / / 8
alert(secondHalfDataView.byteLength); / / 8
alert(secondHalfDataView.buffer === buf);  // true

Copy the code

ElementType

// TODO

Byte order

Bytecode refers to a bytecode order contract maintained by computing systems. DataView supports only two conventions: big-endian and small-endian.

Big-endian byte order: Called “network byte order”, meaning that the most significant bit is stored in the first byte and the least significant bit in the last byte.

Small endian: The opposite, that is, the least significant bit is stored in the first byte and the most significant bit in the last byte.

The 16-bit wide number 0x1234 is stored in the small – end CPU memory (assuming it is stored from address 0x4000) as follows:

Memory address 0x4000 0x4001
Store content 0x34 0x12

In big-endian CPU memory, the storage mode is:

Memory address 0x4000 0x4001
Store content 0x12 0x34

Edge cases

DataView must have sufficient buffers to complete reads and writes, otherwise RangeError will be raised

Stereotype array: TODO

Stereotype arrays are another form of ArrayBuffer view. Although conceptually similar to DataView, stereotype arrays differ in that they are specific to an ElementType and follow the system’s native byte order. Stereotyped arrays are designed to improve the efficiency of exchanging binary data with native libraries such as WebGL.

Stereotyped arrays also use array buffers to store data, and array buffers cannot be resized. Therefore, the following methods do not apply to stereotyped arrays:

  • concat()
  • pop()
  • push()
  • shift()
  • splice()
  • unshift()

Stereotype arrays also provide two new methods to quickly copy data outward or inward: set() and subarray().

Underflow and overflow

MAP

A new feature of ECMAScript 6, Map is a new collection type that brings true key/value storage to the language.

Basic API

// Use the new keyword and the Map constructor to create an empty Map
const m = new Map(a);// If you want to initialize the instance while creating it, you can pass the Map constructor an iterable that contains the key/value logarithm.
// Initialize the map with a nested array
const m1 = new Map([["key1"."val1"],
["key2"."val2"],
["key3"."val3"]]); alert(m1.size);/ / 3

// Initializes the map using a custom iterator
const m2 = new Map({[Symbol.iterator]: function* () { 
    yield ["key1"."val1"]; 
    yield ["key2"."val2"]; 
    yield ["key3"."val3"]; }}); alert(m2.size);/ / 3

// Map expected key/value pairs, whether provided or not

const m3 = new Map([[]]);

alert(m3.has(undefined)); // true
alert(m3.get(undefined)); // undefined
Copy the code

After initialization, you can add key/value pairs using the set() method. In addition, you can use get() and has() for queries, to get the number of key/value pairs in the map using the size attribute, and to delete values using delete() and clear().

const m = new Map().set("key1"."val1");
// The set() method returns a mapping instance, so you can concatenate multiple operations, including initialization declarations:
m.set("key2"."val2") .set("key3"."val3");

alert(m.size); / / 3
Copy the code

Unlike Object, which can only use numeric values, strings, or symbols as keys, Maps can use any JavaScript data type as keys. Map uses the SameValueZero comparison operation internally (defined internally by the ECMAScript specification and not available in the language), which is basically the same as using strict object equality criteria to check key matches. Like Object, there is no limit to the value of the map.

const m = new Map(a);const functionKey = function() {};
const symbolKey = Symbol(a);const objectKey = new Object(a); m.set(functionKey,"functionValue");
m.set(symbolKey, "symbolValue"); 
m.set(objectKey, "objectValue");

alert(m.get(functionKey)); // functionValue
alert(m.get(symbolKey)); // symbolValue
alert(m.get(objectKey)); // objectValue

// SameValueZero comparison means that individual instances do not conflict
alert(m.get(function() {})); // undefined


// As with strict equality, objects and other "collection" types used as keys and values in maps remain unchanged when their contents or attributes are modified:
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"]

// SameValueZero comparisons can also lead to unexpected conflicts

const m = new Map(a);const a = 0/"".// NaN
			b = 0/"".// NaN
			pz = +0,
			nz = -0;

alert(a === b); // false
alert(pz === nz); // true
m.set(a, "foo"); m.set(pz, "bar");
alert(m.get(b)); // foo 
alert(m.get(nz)); // bar
Copy the code

SameValueZero is an equality comparison algorithm added to the ECMAScript specification. For ECMAScript equivalency comparisons, see the articles Equality Warmth and Sameness in the MDN documentation

Sequence and iteration

One major difference from the Object type is that Map instances maintain the insertion order of key-value pairs, so they can perform iterative operations based on the insertion order.

// A mapping instance can provide an Iterator that generates arrays of [key, value] in insert order. This iterator can be obtained through the entries() method (or the symbol.iterator property, which references entries()) :
const m = new Map([["key1"."val1"], ["key2"."val2"], ["key3"."val3"]]); alert(m.entries === m[Symbol.iterator]); // true

for (let pair of m.entries()) { alert(pair); } 
// [key1,val1] // [key2,val2] // [key3,val3]

for (let pair of m[Symbol.iterator]()) { alert(pair); }
// [key1,val1] // [key2,val2] // [key3,val3]



Since entries() are the default iterator, you can extend maps directly to turn them into arrays
console.log([...m]); 
// [[key1,val1],[key2,val2],[key3,val3]]


// Keys and values can be modified during iterator traversal, but references inside the map cannot be modified.
const m1 = new Map([["key1"."val1"]]);// The original value of the string as a key cannot be modified
for (let key of m1.keys()) {
key = "newKey";
alert(key); 
alert(m1.get("key1"));
}

const keyObj = {id: 1};
const m = new Map([ [keyObj, "val1"]]);// Changed the attributes of the object as the key, but the object still references the same value inside the map
for (let key of m.keys()) {
	key.id = "newKey";
	alert(key); // {id: "newKey"}
  alert(m.get(keyObj));  // val1
}
alert(keyObj); // {id: "newKey"}
Copy the code

Select Object or Map

For most Web development tasks, the choice between Object and Map is a matter of personal preference, with little impact. However, for developers who care about memory and performance, there are significant differences between objects and maps.

  1. Memory footprint The engineering level implementation of Object and Map varies significantly between browsers, but the amount of memory used to store a single key/value pair increases linearly with the number of keys. Given a fixed size of memory, Map can store approximately 50% more key/value pairs than Object.

  2. Insert performance Inserting new key/value pairs into Object and Map costs roughly the same, although Map is generally a little faster across all browsers. For both types, the insertion speed does not increase linearly with the number of key/value pairs. If the code involves a lot of inserts, then clearly the Map performs better.

  3. Unlike insertion, finding key/value pairs from large objects and maps has minimal performance differences, but objects can sometimes be faster if only a few key/value pairs are included.

  4. Delete the performance

    The e performance of using delete to remove the Object property has long been criticized, and it still is in many browsers. For most browser engines, Map’s delete() operation is faster than insert and lookup. If your code involves a lot of deletions, you should definitely choose Map.

WeakMap

The addition of “WeakMap” to ECMAScript 6 is a new collection type that brings enhanced key/value pair storage to the language. WeakMap is a “sibling” type of Map and its API is also a subset of Map. The “weak” in WeakMap describes how the JavaScript garbage collector treats the key in the “weak map”.

Basic API

A key in a weak map can only be Object or of a type inherited from Object. Attempting to set a key with a non-object type raises TypeError. There is no restriction on the type of value.

If you want to populate a weak map at initialization, the constructor can receive an iterable that contains an array of key/value pairs. Each key/value in the iterable is inserted into the new instance in iteration order

// If only one key is invalid, an error will be thrown, causing the entire initialization to fail
const wm2 = new WeakMap([
	[key1, "val1"],
	["BADKEY"."val2"],
	[key3, "val3"]]);// TypeError: Invalid value used as WeakMap key 
typeof wm2; // ReferenceError: wm2 is not defined

// Raw values can be wrapped as objects and then used as keys
const stringKey = new String("key1"); 
const wm3 = new WeakMap([ stringKey, "val1" ]);
alert(wm3.get(stringKey)); // "val1"
Copy the code

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

Weak bond

“Weak” in WeakMap means that the key of weak mapping is “held weakly”. This means that these keys are not formal references and do not prevent garbage collection. Note, however, that a reference to a value in a weak map is not “weakly held.” As long as the key exists, the key/value pair exists in the map and is treated as a reference to the value, so it is not garbage collected.

const wm = new WeakMap(a); wm.set({},"val");

The set() method initializes a new object and uses it as the key of a string. Because there is no other reference to the object, the object key is garbage collected when this line of code completes. The key/value pair then disappears from the weak map, leaving it as an empty map. In this case, because the value is also not referenced, the value itself becomes a target for garbage collection when the key/value pair is destroyed.

// A slightly different example:

const wm = new WeakMap(a);const container = {
	key: {}}; wm.set(container.key,"val");
function removeReference() {
container.key = null; 
}
// This time, the Container object maintains a reference to a weakly mapped key, so the object key is not a target for garbage collection. However, if removeReference() is called, the last reference to the key object is destroyed, and the garbage collector can clean up the key/value pair.
Copy the code

Non-iterable key

Because key/value pairs in a WeakMap can be destroyed at any time, there is no need to provide the ability to iterate over their key/value pairs. Of course, you don’t need to destroy all the keys/values at once like clear(). WeakMap does not have this method. Because it is impossible to iterate, it is also impossible to get a value from a weak map without knowing the object reference. Even if the code can access the WeakMap instance, there is no way to see the contents.

The reason why a WeakMap instance restricts the use of objects as keys is to ensure that values can only be obtained through a reference to the key object. If raw values were allowed, there would be no way to distinguish between a string literal used at initialization and an equal string used after initialization.

Use weak mapping

A WeakMap instance is very different from an existing JavaScript object, and it may not be easy to clarify how you should use it. There is no single answer to this question, but many strategies have emerged.

  1. Private variables

    const wm = new WeakMap(a);class User { 
      constructor(id) {
    	this.idProperty = Symbol('id');
    	this.setId(id);
      }
      setPrivate(property, value) { 
        const privateMembers = wm.get(this) | | {}; privateMembers[property] = value; wm.set(this, privateMembers);
      }
    
    	getPrivate(property) { return wm.get(this)[property]; }
    
    	setId(id) { this.setPrivate(this.idProperty, id); }
    
    	getId() { 
      	return this.getPrivate(this.idProperty); }}const user = new User(123);
    alert(user.getId()); / / 123
    user.setId(456);
    alert(user.getId()); / / 456
    
    // Not really private
    alert(wm.get(user)[user.idProperty]); / / 456
    
    WeakMap can be wrapped around a closure so that the WeakMap is completely isolated from the outside world.
    const User = (() = > {
      const wm = new WeakMap(a);class User { 
        constructor(id) {
        this.idProperty = Symbol('id');
        this.setId(id);
        }
        setPrivate(property, value) { 
          const privateMembers = wm.get(this) | | {}; privateMembers[property] = value; wm.set(this, privateMembers);
        }
    
        getPrivate(property) { return wm.get(this)[property]; }
    
        setId(id) { this.setPrivate(this.idProperty, id); }
    
        getId() { 
          return this.getPrivate(this.idProperty); }}returnUser; }) ();Copy the code
  2. DOM node metadata

    // Because WeakMap instances do not interfere with garbage collection, they are ideal for storing associated metadata. Consider the following example, which uses a regular Map:
    const m = new Map(a);const loginButton = document.querySelector('#login');
    
    // Associate some metadata with this node
    m.set(loginButton, {disabled: true});
    // Suppose that after the above code is executed, the page is changed by JavaScript and the original login button is removed from the DOM tree. But because the reference to the button remains in the map, the corresponding DOM node remains in memory unless it is explicitly removed from the map or until the map itself is destroyed.
    
    // If the weak mapping is used here, as shown in the following code, the garbage collector can immediately free the memory of the node as soon as it is removed from the DOM tree (assuming there is no other reference to the object) :
    
    const wm = new WeakMap(a);const loginButton = document.querySelector('#login');
    // Associate some metadata with this node
    wm.set(loginButton, {disabled: true});
    Copy the code

Set

ECMAScript 6’s new Set is a new collection type that brings collection data structures to the language. Sets are in many ways like enhanced maps because most of their apis and behaviors are common.

Basic API

// Initialize the empty collection
const m = new Set(a);// Initialize the collection with an array
const s1 = new Set(["val1"."val2"."val3"]);

alert(s1.size); / / 3

// Initialize the collection with a custom iterator
const s2 = new Set({[Symbol.iterator]: function* () {
    yield "val1"; 
    yield "val2"; 
    yield "val3"; }}); alert(s2.size);Copy the code

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

Like a Map, a Set can contain any JavaScript data type as a value. Collections also use the SameValueZero operation (defined internally by ECMAScript and not available in the language), which is basically equivalent to using strict object equality standards to check the match of values.

The add() and delete() operations are idempotent. Delete () returns a Boolean value indicating whether a value to be deleted exists in the collection:

Idempotent: In programming, an idempotent operation is characterized by any number of executions having the same effect as a single execution. An idempotent function, or idempotent method, is a function that can be executed repeatedly with the same parameters and achieve the same results

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

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

Sequence and iteration

Set maintains the order in which values are inserted, and therefore supports sequential iteration.

// The entries() method of the collection returns an iterator that produces an array of two elements, repeated occurrences of each value in the collection, in insertion order:

const s = new Set(["val1"."val2"."val3"]);

for (let pair of s.entries()) { console.log(pair); } 
// ["val1", "val1"] // ["val2", "val2"] // ["val3", "val3"]

const s1 = new Set(["val1"."val2"."val3"]);

s1.forEach((val, dupVal) = > alert(`${val} -> ${dupVal}`));
// val1 -> val1 // val2 -> val2 // val3 -> val3
Copy the code

Define the formal collection operation: TODO

WeakSet

WeakSet, a new collection type added to ECMAScript 6, brings a collection data architecture to the language. WeakSet is a “sibling” type of Set, and its API is also a subset of Set. The “weak” in WeakSet describes how the JavaScript garbage collector treats the “weak set” median value.

A value in a weak collection can only be Object or a type that inherits from Object. Attempting to set a value that is not an Object raises TypeError.

Initialization is an all-or-nothing operation, and as long as one value is invalid an error is thrown, causing the entire initialization to fail.

After initialization, new values can be added using add(), queried using has(), or deleted using delete()

Weak value

const ws = new WeakSet(a); ws.add({});The add() method initializes a new object and uses it as a value. Because there are no other references to the object, the object value is garbage collected when this line of code completes. The value then disappears from the weak set, leaving it as an empty set.

const ws = new WeakSet(a);const container = { val: {}}; ws.add(container.val);function removeReference() { container.val = null; }

// This time, the Container object maintains a reference to the weak collection value, so the object value is not a target for garbage collection. However, if removeReference() is called, the last reference to the value object is destroyed, and the garbage collector can clean up the value.

Copy the code

Non-iterable value

Using weak sets

A WeakSet instance is not as useful as a WeakMap instance. However, weak sets are still valuable when it comes to labeling objects.

const disabledElements = new Set(a);const loginButton = document.querySelector('#login');

// Label this node "disabled" by adding the corresponding collection
disabledElements.add(loginButton);
// In this way, you can check whether the element is disabled by checking whether it is in disabledElements. However, if an element is removed from the DOM tree, its reference remains in the Set, so the garbage collector cannot reclaim it.


const disabledElements = new WeakSet(a);const loginButton = document.querySelector('#login');

// Label this node "disabled" by adding the corresponding collection
disabledElements.add(loginButton);
// Thus, as soon as any element in WeakSet is removed from the DOM tree, the garbage collector can ignore its existence and immediately free its memory (assuming no other place to reference the object).


Copy the code

Iteration and extension operations

There are four native collection types that define default iterators:

  • Array
  • All stereotype array
  • Map
  • Set

Many other built-in types also implement the Iterable interface

  • string
  • The arguments object
  • DOM collection type such as NodeList

Three types do not implement iterator factory functions

  • Number
  • Boolean
  • Object

This means that all of the above types that define iterators support sequential iteration and can be passed into for-of loops.

This also means that all of these types are compatible with extension operators.