[Red Treasure Book Notes simplified version] Chapter 6 collection reference types

catalogue

6.1 Object type

6.2 Array type

6.2.1 creating arrays

6.2.2 array vacancy  

6.2.3 array index

6.2.4 detection array

6.2.5 iterator method  

6.2.6 copying and filling methods

6.2.7   Conversion method

6.2.8   Stack method

6.2.9   Queue method

6.2.10   Reordering method

6.2.11   Operation method

6.2.12   Location method

6.2.13   Iterative method

6.2.14   Merging method

6.3 training array

6.3.1 history

6.3.2 ArrayBuffer

6.3.3 DataView

6.4 Map

6.4.1 basic API

6.4.2 sequence and iteration

6.4.3 select Object or Map

6.5 WeakMap

6.5.1 basic API

6.5.2 weak bond

6.5.3 non iterative keys

6.6 Set

6.6.1 basic API

6.6.2 sequence and iteration

6.6.3 define formal collection operations

6.7 WeakSet

6.7.1 basic API

6.7.2 weak value

6.7.3 non iterative value

6.7.4 using weak sets

6.8 iteration and expansion operations

6.9 summary

6.1 Object type

There are two ways to create an Object instance. The first is to use the new operator followed by the Object constructor:

var person = new Object(); 
person.name = "Nicholas"; 
person.age = 29;

Another way is to use object literal notation. Object literal is a short form of object definition, which aims to simplify the process of creating objects with a large number of attributes:

var person = { 
 name : "Nicholas", 
 age : 29 
}; 

6.2 Array type

In addition to Object, Array type is probably the most commonly used type in ECMAScript. Moreover, arrays in ECMAScript are quite different from arrays in most other languages. Although ECMAScript arrays and arrays in other languages are ordered lists of data, unlike other languages, each item of ECMAScript arrays can hold any type of data. That is, you can use the first position of the Array to save the string, the second position to save the value, the third position to save the Object, and so on. Moreover, the size of ECMAScript Array can be dynamically adjusted, that is, it can automatically grow with the addition of data to accommodate new data.

6.2.1 creating arrays

There are two basic ways to create arrays. The first is to use the Array constructor:

// Create an Array using the Array constructor
var colors = new Array();

// If you know in advance the number of items to be saved in the array, you can also pass the number to the constructor, and the number will automatically become length
 The value of the property.
var colors = new Array(20); 

// You can also omit the new operator when using the Array constructor
var colors = Arrays(3);

// You can also pass the items that should be included in the Array to the Array constructor.
var colors = new Array("red", "blue", "green");

  The second basic way to create an array is to use array literal notation:

var colors = ["red", "blue", "green"]; // Create an array of 3 strings
var names = []; // Create an empty array
var values = [1,2,]; // Don't do that! An array of 2 or 3 items is created
var options = [,,,,,]; // Don't do that! An array of 5 or 6 items is created

var colors = ["red", "blue", "green"]; // Define an array of strings
alert(colors[0]); // Show first item
colors[2] = "black"; // Amend item 3
colors[3] = "brown"; // Add the fourth item

The length attribute of an array is characteristic -- it is not read-only. Therefore, by setting this property, you can remove items from the end of the array or add new items to the array.

var colors = ["red", "blue", "green"]; // Create an array of 3 strings
colors.length = 2; 
alert(colors[2]); //undefined

var colors = ["red", "blue", "green"]; // Create an array of 3 strings
colors.length = 4; 
alert(colors[3]); //undefined 

// Although the colors array contains three items, its length property is set to 4. Position 3 does not exist in this array,
So accessing the value of this location gets a special value undefined

// The length attribute also makes it easy to add a new item to the end of the array
var colors = ["red", "blue", "green"]; // Create an array of 3 strings
colors[colors.length] = "black"; //(in position 3) add a color
colors[colors.length] = "brown"; //(at position 4) add another color

6.2.2 array vacancy  

6.2.3 array index

6.2.4 detection array

The classic problem of determining whether an object is an array. For a web page or a global scope, you can get satisfactory results by using the instanceof operator:

The problem with the instanceof operator is that it assumes only one global execution environment. If the web page contains multiple frames, there are actually more than two different global execution environments, so there are more than two different versions of Array constructors. If you pass in an Array from one frame to another, the passed in Array has different constructors from the Array natively created in the second frame.  

To solve this problem, ECMAScript 5 adds the Array.isArray() method. The purpose of this method is to finally determine whether a value is an array or not, regardless of the global execution environment in which it is created.

6.2.5 iterator method  

6.2.6 copying and filling methods

6.2.7   Conversion method

All objects have toLocaleString(), toString(), and valueOf() methods. The toString() method of calling the array returns a comma separated string that is spliced by the string of each value in the array. The call to valueOf() returns an array.

var colors = ["red", "blue", "green"]; // Create an array of 3 strings
alert(colors.toString()); // red,blue,green 
alert(colors.valueOf()); // red,blue,green 
alert(colors); // red,blue,green 

We first explicitly call the toString() method to return the string representation of the array. The string representation of each value is spliced into a string separated by commas. The valueOf() method is then called, and the last line of code passes the array directly to alert(). Because alert() wants to receive string parameters, it calls the toString() method in the background, resulting in the same result as calling the toString() method directly.  

6.2.8   Stack method

ECMAScript arrays also provide a way to make arrays behave like other data structures. Specifically, an array can behave like a stack, which is a data structure that can restrict the insertion and deletion of items. Stack is a LIFO (last in first out) data structure, that is, the newly added items are removed at the earliest. The insertion (called push) and removal (called Pop-Up) of items in the stack only occur in one position - the top of the stack. ECMAScript specifically provides push() and pop() methods for arrays to achieve stack like behavior.

/**
push()Method can receive any number of parameters, add them to the end of the array one by one, and return the length of the modified array.
The pop() method removes the last item from the end of the array, reduces the length value of the array, and then returns the removed item
*/
var colors = new Array(); // Create an array
var count = colors.push("red", "green"); // Push in two items
alert(count); //2 
count = colors.push("black"); // Push in another item
alert(count); //3 
var item = colors.pop(); // Get the last item
alert(item); //"black" 
alert(colors.length); //2 
// Examples used with other array methods
var colors = ["red", "blue"]; 
colors.push("brown"); // Add another item
colors[3] = "black"; // Add an item
alert(colors.length); // 4 
var item = colors.pop(); // Get the last item
alert(item); //"black" 

6.2.9   Queue method

The access rule of stack data structure is LIFO (last in first out), while the access rule of queue data structure is FIFO (first in first out). The queue adds items at the end of the list and removes items from the front of the list. Since push() is a method to add items to the end of the array, to simulate a queue, you only need a method to get items from the front of the array. The array method to do this is shift(), which can remove the first item in the array and return it, while reducing the length of the array by 1. Using the shift() and push() methods in combination, you can use arrays as you would a queue.

var colors = new Array(); //Create an array
var count = colors.push("red", "green"); //Push in two items
alert(count); //2 
count = colors.push("black"); //Push in another item
alert(count); //3 
var item = colors.shift(); //Get the first item
alert(item); //"red" 
alert(colors.length); //2

ECMAScript also provides an unshift() method for arrays. As the name suggests, unshift() is the opposite of shift(): it can add any item to the front of the array and return the length of the new array. Therefore, using the unshift() and pop() methods at the same time, you can simulate the queue from the opposite direction, that is, add items at the front of the array and remove items from the end of the array.

var colors = new Array(); //Create an array
var count = colors.unshift("red", "green"); //Push in two items
alert(count); //2
count = colors.unshift("black"); //Push in another item
alert(count); //3 
var item = colors.pop(); //Get the last item
alert(item); //"green" 
alert(colors.length); //2 

  This example creates an array and uses the unshift() method to push in three values successively. First "red" and "green", then "black". The order of items in the array is "black", "red" and "green". When the pop() method is called, the last item, green, is removed and returned.

6.2.10   Reordering method

There are already two methods in the array that can be used directly for reordering: reverse() and sort(). As some readers may have guessed, the reverse () method reverses the order of array items.

var values = [1, 2, 3, 4, 5]; 
values.reverse(); 
alert(values); //5,4,3,2,1 

Here, the initial value and order of the array are 1, 2, 3, 4 and 5. After calling the reverse() method of the array, the order of its values becomes 5, 4, 3, 2 and 1. The function of this method is quite intuitive, but it is not flexible enough, so there is the sort() method.  

By default, the sort() method sorts the array items in ascending order -- that is, the smallest value comes first and the largest value comes last. In order to sort, the sort() method calls the toString() transformation method of each array item, and then compares the resulting strings to determine how to sort. Even if every item in the array is numeric, the sort() method compares strings.  

It can be seen that even if there is no problem with the order of values in the example, the sort() method will change the original order according to the result of the test string. Although the value 5 is less than 10, "10" is in front of "5" during string comparison, so the order of the array is modified.

This sort method is not the best scheme in many cases. Therefore, the sort() method can take a comparison function as an argument so that we can specify which value precedes which value.

  This comparison function can be applied to most data types by passing it as an argument to the sort() method

/**
After passing the comparison function to the sort() method, the values remain in the correct ascending order. Of course, you can also compare functions
 The results of descending sorting can be generated as long as the values returned by the comparison function are exchanged.
*/
function compare(value1, value2) { 
 if (value1 < value2) { 
 return 1; 
 } else if (value1 > value2) { 
 return -1; 
 } else { 
 return 0; 
 } 
} 
var values = [0, 1, 5, 10, 15]; 
values.sort(compare); 
alert(values); // 15,10,5,1,0 

Supplement: sort() method

6.2.11   Operation method

1. concat()

ECMAScript provides many methods for manipulating items already contained in an array. Among them, the concat() method can create a new array based on all items in the current array. Specifically, this method will first create a copy of the current array, then add the received parameters to the end of the copy, and finally return the newly constructed array. Without passing arguments to the concat() method, it simply copies the current array and returns a copy. If one or more arrays are passed to the concat() method, the method adds each of these arrays to the result array. If the values passed are not arrays, they are simply added to the end of the result array.

var colors = ["red", "green", "blue"]; 
var colors2 = colors.concat("yellow", ["black", "brown"]); 
alert(colors); //red,green,blue 
alert(colors2); //red,green,blue,yellow,black,brown

2. slice()

slice(), which can create a new array based on one or more items in the current array. The slice() method can accept one or two parameters, that is, the start and end positions of the item to be returned. In the case of only one parameter, the slice() method returns all items from the position specified by the parameter to the end of the current array. If there are two arguments, the method returns the item between the start and end positions -- but not the item at the end position. Note that the slice() method does not affect the original array.  

var colors = ["red", "green", "blue", "yellow", "purple"]; 
var colors2 = colors.slice(1); 
var colors3 = colors.slice(1,4); 
alert(colors2); //green,blue,yellow,purple 
alert(colors3); //green,blue,yellow 

  Note: if there is a negative number in the parameter of slice() method, the array length plus the number is used to determine the corresponding position. For example, calling slice(-2,-1) in an array containing five items yields the same result as calling slice(3,4). If the end position is less than the start position, an empty array is returned.

3. splice() 

The main purpose of splice() is to insert items into the middle of the array, but there are three ways to use this method:

  • Delete: any number of items can be deleted. Only two parameters need to be specified: the position of the first item to be deleted and the number of items to be deleted. For example, splice(0,2) deletes the first two items in the array.
  • Insert: you can insert any number of items into the specified location. You only need to provide three parameters: starting location, 0 (number of items to be deleted) and items to be inserted. If you want to insert multiple items, you can pass in the fourth, fifth, or any number of items. For example, splice(2,0,"red","green") will insert the strings "red" and "green" from position 2 of the current array.
  • Replace: you can insert any number of items into the specified location and delete any number of items at the same time. You only need to specify three parameters: starting location, number of items to delete and any number of items to insert. The number of items inserted does not have to be equal to the number of items deleted. For example, splice (2,1,"red","green") will delete the item at position 2 of the current array, and then insert the strings "red" and "green" from position 2.

The splice() method always returns an array containing items deleted from the original array (or an empty array if no items were deleted).

var colors = ["red", "green", "blue"]; 
var removed = colors.splice(0,1); // Delete the first item
alert(colors); // green,blue 
alert(removed); // red, the returned array contains only one item
removed = colors.splice(1, 0, "yellow", "orange"); // Insert two items starting at position 1
alert(colors); // green,yellow,orange,blue 
alert(removed); // An empty array is returned
removed = colors.splice(1, 1, "red", "purple"); // Insert two items and delete one
alert(colors); // green,red,purple,orange,blue 
alert(removed); // yellow, the returned array contains only one item

6.2.12   Location method

ECMAScript 5 adds two location methods for array instances: indexOf() and lastIndexOf(). Both methods take two parameters: the item to find and, optionally, the index that represents the starting point of the search. The indexof () method searches backward from the beginning of the array (position 0), and the lastIndexOf () method searches forward from the end of the array.         

Both methods return the position of the item to be found in the array, or - 1 if it is not found. The congruent operator is used when comparing the first parameter with each item in the array; That is, the items to be found must be strictly equal (just like using = = =).

var numbers = [1,2,3,4,5,4,3,2,1]; 
alert(numbers.indexOf(4)); //3
alert(numbers.lastIndexOf(4)); //5 
alert(numbers.indexOf(4, 4)); //5 
alert(numbers.lastIndexOf(4, 4)); //3 
var person = { name: "Nicholas" }; 
var people = [{ name: "Nicholas" }]; 
var morePeople = [person]; 
alert(people.indexOf(person)); //-1 
alert(morePeople.indexOf(person)); //0 

6.2.13   Iterative method

ECMAScript 5 defines five iterative methods for arrays. Each method takes two parameters: the function to run on each item and (optionally) the scope object that runs the function -- the value that affects this. The functions passed into these methods receive three parameters: the value of the array item, the position of the item in the array, and the array object itself.

  • every(): run the given function for each item in the array. If the function returns true for each item, it returns true.
  •   filter(): run the given function for each item in the array, and returning the function will return an array of true items.
  •   forEach(): runs the given function for each item in the array. This method has no return value.
  •   map(): run the given function for each item in the array and return the array composed of the results of each function call.
  •   some(): run the given function for each item in the array. If the function returns true for any item, it returns true. None of the above methods will modify the values contained in the array.

every()  ,some() :

var numbers = [1,2,3,4,5,4,3,2,1]; 
var everyResult = numbers.every(function(item, index, array){ 
 return (item > 2); //Traverse each item. If all items are greater than 2, return true; otherwise, return false
}); 
alert(everyResult); //false 
var someResult = numbers.some(function(item, index, array){ 
 return (item > 2); //Traverse each item. If at least one item is greater than 2, it returns true; otherwise, it returns false
}); 
alert(someResult); //true 

filter() : 

var numbers = [1,2,3,4,5,4,3,2,1]; 
var filterResult = numbers.filter(function(item, index, array){ 
 return (item > 2); //Filter out item s greater than 2 to form a new array
}); 
alert(filterResult); //[3,4,5,4,3] 

 map() :

var numbers = [1,2,3,4,5,4,3,2,1]; 
var mapResult = numbers.map(function(item, index, array){ 
 return item * 2; //Process each item and return a new array
}); 
alert(mapResult); //[2,4,6,8,10,8,6,4,2] 

forEach():

It simply runs the passed in function on each item in the array. This method has no return value, which is essentially the same as iterating over an array using a for loop.  

var numbers = [1,2,3,4,5,4,3,2,1]; 
numbers.forEach(function(item, index, array){ 
 //Perform some actions 
});

6.2.14   Merging method

ECMAScript 5 also adds two methods to merge arrays: reduce() and reduceRight(). Both methods iterate over all the items of the array and then build a final returned value. The reduce () method starts from the first item of the array and traverses one by one to the end. reduceRight() starts from the last item of the array and traverses forward to the first item

/**
When the callback function is executed for the first time, prev is 1 and cur is 2. The second time, prev is 3 (the result of 1 plus 2) and cur is 3 (array)
The third item of). This process will continue until each item in the array is accessed again, and finally the result is returned
*/
var values = [1,2,3,4,5]; 
var sum = values.reduce(function(prev, cur, index, array){ 
 return prev + cur; 
}); 
alert(sum); //15 

    
/**
In this example, the callback function is executed for the first time. prev is 5 and cur is 4. Of course, the end result is the same, because all the are executed
 Is a simple addition operation.
*/
var values = [1,2,3,4,5]; 
var sum = values.reduceRight(function(prev, cur, index, array){ 
 return prev + cur; 
}); 
alert(sum); //15 

6.3 training array

6.3.1 history

As early as 2006, Mozilla, Opera and other browser providers experimentally added a programming platform for rendering complex graphics applications in the browser without installing any plug-ins. The goal is to develop a set of JavaScript API s to take full advantage of the 3D graphics API and GPU acceleration to render complex graphics on elements. In earlier versions of WebGL, performance problems occurred because of the mismatch between JavaScript arrays and native arrays.

Mozilla implements the canvas loadarray to solve this problem. This is a C language style floating-point value array that provides a JavaScript interface. The JavaScript runtime uses this type to allocate, read, and write arrays. This array can be passed directly to the underlying graphics driver API or obtained directly from the underlying graphics driver API. Finally, canvas loadarray became Float32Array, the first "type" available in today's stereotyped array.

6.3.2 ArrayBuffer

Float32Array is actually a "view" that allows the JavaScript runtime to access a piece of pre allocated memory called ArrayBuffer. ArrayBuffer is the basic unit of all training arrays and view references. ArrayBuffer() is a normal 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 

// Once the ArrayBuffer is created, it cannot be resized. However, you can use slice() to copy all or part of it into a new instance:
const buf1 = new ArrayBuffer(16);
const buf2 = buf1.slice(4, 12);
alert(buf2.byteLength); // 8 

ArrayBuffer is somewhat similar to malloc() in C + +, but there are several obvious differences.

  •   malloc() returns a null pointer when allocation fails. ArrayBuffer throws an error when allocation fails.
  • malloc() can utilize virtual memory, so the maximum allocable size is limited only by addressable system memory. The memory allocated by ArrayBuffer cannot exceed Number.MAX_SAFE_INTEGER byte.
  • The malloc() call succeeds and does not initialize the actual address. Declaring ArrayBuffer initializes all binary bits to 0.
  • Heap memory allocated through malloc() cannot be used by the system unless free() is called or the program exits. The heap memory allocated by declaring ArrayBuffer can be garbage collected without manual release.

You cannot read or write the contents of an ArrayBuffer simply by referencing it. To read or write to the ArrayBuffer, you must pass through the view. Views have different types, but they all refer to binary data stored in ArrayBuffer.  

6.3.3 DataView

The first view that allows you to read and write ArrayBuffer is DataView. This view is designed for file I/O and network I/O. its API supports a high degree of control over buffered data, but its performance is also poor compared with other types of views. DataView has no preset for buffered content and cannot iterate. You must read or write to an existing ArrayBuffer to create a DataView instance. This instance can use all or part of the ArrayBuffer, and maintains the reference to the buffer instance and the starting position of the view in the buffer

6.4 Map

As a new feature of ECMAScript 6, Map is a new collection type, which brings a real key / value storage mechanism to the language. Most of the features of Map can be implemented through the Object type, but there are still some subtle differences between the two.

6.4.1 basic API

// Initialize mapping using nested arrays
const m1 = new Map([
 ["key1", "val1"],
 ["key2", "val2"],
 ["key3", "val3"]
]);
alert(m1.size); // 3
// Initializing a 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 the expected key / value pair, whether or not provided
const m3 = new Map([[]]);
alert(m3.has(undefined)); // true
alert(m3.get(undefined)); // undefined
const m = new Map();
alert(m.has("firstName")); // false
alert(m.get("firstName")); // undefined
alert(m.size); // 0
m.set("firstName", "Matt")
 .set("lastName", "Frisbie");
alert(m.has("firstName")); // true
alert(m.get("firstName")); // Matt
alert(m.size); // 2
m.delete("firstName"); // Delete only this key / value pair
alert(m.has("firstName")); // false
alert(m.has("lastName")); // true
alert(m.size); // 1
m.clear(); // Clear all key / value pairs in this mapping instance
alert(m.has("firstName")); // false
alert(m.has("lastName")); // false
alert(m.size); // 0 

Object can only use numeric values, strings or symbols as keys. Unlike Map, any JavaScript data type can be used as keys. The SameValueZero comparison operation is used inside the Map (ECMAScript specification is internally defined and cannot be used in the language), which is basically equivalent to using the strict object equality standard to check the key matching. Like object, mapped values are unlimited.

const m = new Map();
const functionKey = function() {};
const symbolKey = Symbol();
const objectKey = new Object();
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
// The SameValueZero comparison means that independent instances do not conflict
alert(m.get(function() {})); // undefined
const m = new Map();
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"] 

6.4.2 sequence and iteration

A major difference from the Object type is that the Map instance maintains the insertion order of key value pairs, so you can perform iterative operations according to the insertion order.

The mapping instance can provide an iterator that can generate an array in the form of [key, value] in insertion order. This iterator can be obtained through the entries() method (or the Symbol.iterator attribute, which references entries())

too entries()Method (or Symbol.iterator Property, which references entries())Get this iterator:
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] 

const m = new Map([
 ["key1", "val1"],
 ["key2", "val2"],
 ["key3", "val3"]
]);
console.log([...m]); // [[key1,val1],[key2,val2],[key3,val3]]
keys()and values()Returns iterators that generate keys and values in insertion order, respectively:
const m = new Map([
 ["key1", "val1"],
 ["key2", "val2"],
 ["key3", "val3"]
]);
for (let key of m.keys()) {
 alert(key);
}
// key1
// key2
// key3
for (let key of m.values()) {
 alert(key);
}
// value1
// value2
// value

6.4.3 select Object or Map

Choosing Object or Map is just a matter of personal preference and has little impact

6.5 WeakMap

The new "weak Map" in ECMAScript 6 is a new collection type, which brings an enhanced key / value pair storage mechanism to the language. WeakMap is the "brother" type of Map, and its API is also a subset of Map. The "weak" in WeakMap describes the way JavaScript garbage collector treats the keys in "weak Map".

6.5.1 basic API

You can instantiate an empty WeakMap using the new keyword:

const wm = new WeakMap();

A key in a weak mapping can only be an Object or a type inherited from Object. Trying to set a key using a non Object will throw a TypeError. There is no limit on the type of value.

const key1 = {id: 1},
      key2 = {id: 2},
      key3 = {id: 3};
// Initializing weak mappings with nested arrays
const wm1 = new WeakMap([
 [key1, "val1"],
 [key2, "val2"],
 [key3, "val3"]
]);
alert(wm1.get(key1)); // val1
alert(wm1.get(key2)); // val2
alert(wm1.get(key3)); // val3
// Initialization is an all or nothing operation
// As long as one key is invalid, an error will be thrown, resulting in the failure of the whole initialization
const wm2 = new WeakMap([
 [key1, "val1"],
 ["BADKEY", "val2"],
 [key3, "val3"]
]);
// TypeError: Invalid value used as WeakMap key
typeof wm2;
// ReferenceError: wm2 is not defined

6.5.2 weak bond

"Weak" in WeakMap means that the keys of weak mapping are "weakly held". This means that these keys are not formal references and will not prevent garbage collection. However, it should be noted that references in the value of weak mapping are not "weakly held" As long as the key exists, the key / value pair exists in the mapping and is treated as a reference to the value, so it will not be garbage collected.

6.5.3 non iterative keys

slightly

6.6 Set

6.6.1 basic API

const s = new Set();
alert(s.has("Matt")); // false
alert(s.size); // 0
s.add("Matt")
 .add("Frisbie");
alert(s.has("Matt")); // true
alert(s.size); // 2
s.delete("Matt");
alert(s.has("Matt")); // false
alert(s.has("Frisbie")); // true
alert(s.size); // 1
s.clear(); // Destroy all values in the collection instance
alert(s.has("Matt")); // false
alert(s.has("Frisbie")); // false
alert(s.size); // 0 

Like a Map, Set can contain any JavaScript data type as a value  

// The add() and delete() operations are idempotent. Delete() returns a Boolean value indicating whether there is a value to delete in the collection:
const s = new Set();
s.add('foo');
alert(s.size); // 1
s.add('foo');
alert(s.size); // 1
// There is this value in the set
alert(s.delete('foo')); // true
// There is no such value in the collection
alert(s.delete('foo')); // false

6.6.2 sequence and iteration

Set maintains the order in which values are inserted, so it supports sequential iteration. The collection instance can provide an Iterator that can generate the contents of the collection in the insertion order. This Iterator can be obtained through the values() method and its alias method keys() (or the Symbol.iterator property, which references values()):

const s = new Set(["val1", "val2", "val3"]);
alert(s.values === s[Symbol.iterator]); // true
alert(s.keys === s[Symbol.iterator]); // true
for (let value of s.values()) {
 alert(value);
}
// val1
// val2
// val3
for (let value of s[Symbol.iterator]()) {
 alert(value);
}
// val1
// val2
// val3 

6.6.3 define formal collection operations

slightly

6.7 WeakSet

The "weak Set" added in ECMAScript 6 is a new Set type, which brings a Set data structure to the language. The "weak Set" is the "brother" type of Set, and its API is also a subset of Set. The "weak" in the "weak Set" describes how the JavaScript garbage collector treats the value of the "weak Set".

6.7.1 basic API

You can instantiate an empty WeakSet with the new keyword:

const ws = new WeakSet();

Values in a weak collection can only be objects or types inherited from objects. Attempting to set a value using a non Object will throw a TypeError. If you want to populate the weak collection during initialization, the constructor can receive an iteratable Object that needs to contain valid values. Each value in an iteratable Object will be inserted into a new instance in iterative order:

const val1 = {id: 1},
 val2 = {id: 2},
 val3 = {id: 3};
// Initializing weak collections with arrays
const ws1 = new WeakSet([val1, val2, val3]);
alert(ws1.has(val1)); // true
alert(ws1.has(val2)); // true
alert(ws1.has(val3)); // true
// Initialization is an all or nothing operation
// As long as one value is invalid, an error will be thrown, resulting in the failure of the whole initialization
const ws2 = new WeakSet([val1, "BADVAL", val3]);
// TypeError: Invalid value used in WeakSet
typeof ws2;
// ReferenceError: ws2 is not defined

6.7.2 weak value

"Weak" in the WeakSet indicates that the values of the weak set are "weakly held". That is, these values are not formal references and will not prevent garbage collection.

const ws = new WeakSet();
ws.add({}); 
/**
add()Method initializes a new object and uses it as a value. Because there are no other references to this object, when
 After this line of code is executed, the object value will be garbage collected. Then, the value will disappear from the weak collection and become
 An empty collection.
*/

6.7.3 non iterative value

Because the values in the WeakSet can be destroyed at any time, it is not necessary to provide the ability to iterate its values. Of course, there is no need for a method like clear() to destroy all values at once. The WeakSet does not have this method. Because it is impossible to iterate, it is also impossible to obtain values from a weak set without knowing the object reference.

The reason why WeakSet restricts the use of objects as values is to ensure that values can only be obtained through the reference of value objects. If original values are allowed, there is no way to distinguish between the literal amount of strings used during initialization and an equal string used after initialization.

6.7.4 using weak sets

slightly

6.8 iteration and expansion operations

There are four native collection types that define default iterators:
 Array
 all training arrays
 Map
 Set

This means that all the above types support sequential iteration and can be passed into a for of loop:
 

let iterableThings = [
 Array.of(1, 2),
 typedArr = Int16Array.of(3, 4),
 new Map([[5, 6], [7, 8]]),
 new Set([9, 10])
];
for (const iterableThing of iterableThings) {
 for (const x of iterableThing) {
 console.log(x);
 }
}
// 1
// 2
// 3
// 4
// [5, 6]
// [7, 8]
// 9
// 10 
let arr1 = [1, 2, 3];
// Copy array to training array
let typedArr1 = Int16Array.of(...arr1);
let typedArr2 = Int16Array.from(arr1);
console.log(typedArr1); // Int16Array [1, 2, 3]
console.log(typedArr2); // Int16Array [1, 2, 3]
// Copy array to map
let map = new Map(arr1.map((x) => [x, 'val' + x]));
console.log(map); // Map {1 => 'val 1', 2 => 'val 2', 3 => 'val 3'}
// Copy array to collection
let set = new Set(typedArr2);
console.log(set); // Set {1, 2, 3}
// Copy Collection back to array
let arr2 = [...set];
console.log(arr2); // [1, 2, 3]
let arr1 = [1, 2, 3];
let arr2 = [...arr1];
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [1, 2, 3]
console.log(arr1 === arr2); // false
 For constructors that expect iteratable objects, you can copy by passing in an iteratable object:
let map1 = new Map([[1, 2], [3, 4]]);
let map2 = new Map(map1);
console.log(map1); // Map {1 => 2, 3 => 4}
console.log(map2); // Map {1 => 2, 3 => 4}
Of course, you can also build some elements of the array:
let arr1 = [1, 2, 3];
let arr2 = [0, ...arr1, 4, 5];
console.log(arr2); // [0, 1, 2, 3, 4, 5]
Shallow copy means that only object references are copied:
let arr1 = [{}];
let arr2 = [...arr1];
arr1[0].foo = 'bar';
console.log(arr2[0]); // { foo: 'bar' } 

6.9 summary

Objects in JavaScript are reference values, and you can create specific types of objects through several built-in reference types.

  • Reference types are similar to classes in traditional object-oriented programming languages, but their implementation is different.
  • Object type is a basic type from which all reference types inherit the basic behavior.
  • The Array type represents an ordered set of values and provides the ability to manipulate and convert values.
  • The training array contains a set of different reference types, which are used to manage the types of values in memory.
  • The Date type provides information about the Date and time, including the current Date and time and the calculation.
  • RegExp type is the interface of regular expressions supported by ECMAScript. It provides the capabilities of most basic regular expressions and some advanced regular expressions.

The unique point of JavaScript is that functions are actually instances of Function type, which means that functions are also objects. Since functions are objects, they have methods that can enhance their own behavior.

Because of the existence of primitive value wrapper types, primitive values in JavaScript can have object like behavior. There are three primitive value wrapper types: Boolean, Number and String. They all have the following characteristics.

  • Each wrapper type maps to a primitive type with the same name.
  • When accessing the original value in read mode, the background will instantiate an original value wrapper object through which data can be manipulated.
  • As soon as the statement involving the original value is executed, the wrapper object will be destroyed immediately.

JavaScript also has two built-in objects that exist at the beginning of code execution: Global and math. Among them, the Global object is not directly accessible in most ECMAScript implementations. However, the browser implements Global as a window object. All Global variables and functions are properties of the Global object. The Math object contains attributes and methods that assist in complex mathematical calculations.

ECMAScript 6 adds a batch of reference types: Map, WeakMap, Set and WeakSet. These types provide new capabilities for organizing application data and simplifying memory management.

Tags: Javascript ECMAScript

Posted on Wed, 27 Oct 2021 10:03:31 -0400 by jmartinez