1, the Object

  • Create a way
    • The new operator and Object constructor
    • Object literals
  • When an Object is defined using Object literal notation, the Object constructor is not called
  • In parentheses, variables can be passed

2, Array

Create an array

  • Array constructor let colors = new Array()

  • Let colors = new Array(20)

  • Let colors = new Array(“red”, “blue”, “green”)

  • Passing in a value

    • Numeric values create arrays of numeric length
    • Otherwise, create an array containing only that value
  • Omitting the new operator gives the same result

  • Array literals let colors = [1,2]

    • The Array constructor is not called
  • Array.from()

    • Convert an array of classes to an instance of an array
    // ["M","a","t","t"]
    Array.from("Matt") 
    
    const m = new Map().set(1.2)
              .set(3.4)
    const s = new Set().add(1)
              .add(2)
              .add(3)
              .add(4)
    Array.from(m) / / [[1, 2], [3, 4]]
    Array.from(s) / / [1, 2, 3, 4]
    Copy the code
    • Shallow copy of an existing array
    const a1 = [1.2.3.4];
    const a2 = Array.from(a1)
    a1        / / [1, 2, 3, 4]
    a1 === a2 // false
    Copy the code
    • You can use any iterable
    const iter = {
      *[Symbol.iterator]() {
        yield 1;
        yield 2;
        yield 3;
        yield 4; }}Array.from(iter) / / [1, 2, 3, 4]
    Copy the code
    • Arguments objects can be converted to arrays
    function getArgsArray() {
      return Array.from(arguments)
    }
    getArgsArray(1.2.3.4) / / [1, 2, 3, 4]
    Copy the code
    • From () transforms custom objects with the necessary attributes
    const arrayLikeObj = {
      0: 1.1: 2.2: 3.3: 4.length: 4
    }
    Array.from(arrayLikeObj) / / [1, 2, 3, 4]
    Copy the code
    • The second argument is an optional mapping function argument

      • Enhance the value of the new Array directly, without creating an intermediate Array with array.from ().map()
    • The third argument is used to receive the this value in the mapping function

      • Arrow functions do not apply
      const a1 = [1.2.3.4]
      const a2 = Array.from(a1, x= >x**2)
      const a3 = Array.from(a1, function(x){return x**this.exponent}, {exponent: 2})
      a2 // [1, 4, 9, 16]
      a3 // [1, 4, 9, 16]
      Copy the code
  • Array.of()

    • Converts a set of parameters to an array
    • Instead of an Array. The prototype. Slice. The call (the arguments)
    Array.of(1.2.3.4) / / [1, 2, 3, 4]
    Array.of(undefined) // [undefined]
    Copy the code

2, array empty

  • When a literal is initialized, a space can be created with a string of commas
  • Es6 considers undefined
  • Behavior inconsistency
    • Map skips empty positions
    • Join treats empty positions as empty strings

3. Array index

  • If you set a value to an index that exceeds the maximum index, the array size automatically expands to +1 for that index

  • The length attribute can be modified to remove or add elements

    let c = [1.2.3]
    c[c.length] = 4
    c[c.length] = 5
    Copy the code

4. Check the array

  • Determine if an object is an array (with only one global scope)
value instanceof Array
Copy the code
  • If you have multiple scopes
Array.isArray(value)
Copy the code

5. Iterator method

  • keys()
    • Returns an array index iterator
  • values()
    • Returns an array element iterator
  • entries()
    • Returns an iterator for index/value pairs
const a = ["foo"."bar"."baz"]

Array.from(a.keys())   / / [0, 1, 2]
Array.from(a.values()) // ["foo", "bar", "baz"]
Array.from(a.entries()) // [[0, "foo"], [1, "bar"], [2, "baz"]]

for(const [idx, elem] of a.entries()) {
  alert(idx)
  alert(elem)
}
Copy the code

6. Copy and fill methods

  • copyWithin()

    • Bulk copy
    • The first parameter is the index to start filling in
    • The second argument is the index to start replication (default: 0)
    • The third argument ends the index of the replication (default tail)
    • The negative index counts from the end
    • Insert the contents of the specified range shallow copy array at the beginning of the specified index.
    • Modify the original array
    let ints = [0.1.2.3.4.5.6.7.8.9]
    
    // each time the default is reset to [0,1,2,3,4,5,6,7,8,9]
    ints.copyWithin(5) / /,1,2,3,4,0,1,2,3,4 [0]
    ints.copyWithin(0.5)/ /,6,7,8,9,5,6,7,8,9 [5]
    ints.copyWithin(4.0.3)/ /,1,2,3,0,1,2,7,8,9 [0]
    ints.copyWithin(2.0.6)/ /,1,0,1,2,3,4,5,8,9 [0]
    ints.copyWithin(-4, -7, -3)/ /,1,2,3,4,5,3,4,5,6 [0]
    
    // Ignore index ranges beyond array boundaries, zero length, and in opposite directions
    // Index bottom ignored
    ints.copyWithin(1, -15, -12) / /,1,2,3,4,5,6,7,8,9 [0]
    // Index is too high to ignore
    ints.copyWithin(1.12.15)   / /,1,2,3,4,5,6,7,8,9 [0]
    // The index is ignored in reverse
    ints.copyWithin(2.4.2)     / /,1,2,3,4,5,6,7,8,9 [0]
    // The index section is available
    ints.copyWithin(4.7.10) / /,1,2,3,7,8,9,7,8,9 [0]
    Copy the code
  • fill()

    • Populates an array by inserting all or part of the same values into an existing array
    • The first parameter, the content to fill
    • Second argument, start index (optional)
    • Third argument, end index (optional)
    • The negative index counts from the end
    • Modify the original array
    const zeroes = [0.0.0.0.0]
    
    // reset to [0,0,0,0,0]
    zeroes.fill(5)        / /,5,5,5,5 [5]
    zeroes.fill(6.3)      / /,0,0,6,6 [0]
    zeroes.fill(7.1.3)    / /,7,7,0,0 [0]
    zeroes.fill(8, -4, -1)  / /,8,8,8,0 [0]
    
    // Ignore index ranges beyond array boundaries, zero length, and in opposite directions
    // Index bottom ignored
    zeroes.fill(1, -10, -6) / /,0,0,0,0 [0]
    // Index is too high to ignore
    zeroes.fill(1.10.15) / /,0,0,0,0 [0]
    // The index is ignored in reverse
    zeroes.fill(2.4.2) / /,0,0,0,0 [0]
    // The index section is available
    zeroes.fill(4.3.10) / /,0,0,4,4 [0]
    Copy the code

7. Conversion method

  • ValueOf () returns the array itself
  • ToString () returns a comma-separated string for each value
  • join()
    • By default the comma
    • The passed argument is a delimiter
  • Null and undefined are represented as empty strings

8. Stack method

  • Push ()+pop()
  • Push (), push(
    • Accepts any number of arguments to add to the end of the array
    • Return the latest length
    • Change the original array
  • Pop (), delete
    • Remove the last item and reduce the array length
    • Returns the deleted item
    • Change the original array

9. Queue methods

  • Queue fifO push() + Shift ()
  • shift()
    • Delete the first item of the array and return it
    • The length of the array is reduced by one
  • unshift()
    • In contrast to the shift ()
    • Return array length

10. Sorting methods

  • reverse()

    • Reverse the array
  • sort()

    • Default reordering in ascending order (to string comparison)

    • Receives the comparison function to determine which value comes first

      • Returns a negative value if the first comes before the second
      • Equal returns 0
      • Returns a positive value if the first comes after the second
      // Return negative numbers, the smallest first, in ascending order
      function compare(value1, value2) {
        if(value1 < value2) {
          return -1
        }else if (value1 > value2) {
          return 1
        }
        return 0
      }
      
      // (a,b)=> ab ? 1:0
      
      // If both values are values
      function compare(value1, value2) {
        return value1 - value2
      }
      Copy the code

11. Operation method

  • concat()

    • Creates a new array based on all the elements of the existing array
    • Passing an array adds each item of the array to the result array
    • If the pass is not an array, it is appended directly to the end of the array
    • The original array is unchanged
    • The leveling mode can be rewritten
    let colors = ["red"."green"."blue"]
    let newColors = ["black"."brown"]
    let moreNewColors = {
      [Symbol.isConcatSpreadable]: true.length: 2.0: "pink".1: "cyan"
    }
    
    newColors[Symbol.isConcatSpreadable] = false
    
    // Force no tie
    // ["red","green","blue","yellow",["black", "brown"]]
    colors.concat("yellow",newColors)
    
    // Force a flat array object
    // ["red","green","blue","pink","cyan"]
    colors.concat(moreNewColors)
    Copy the code
  • slice()

    • Creates a new array containing one or more elements of the original array
    • Do not change the original array
    • Parameter one, start indexing
    • Parameter two, end index (not included)
    • Negative value plus array length
  • splice()

    • Basically, you insert elements in the middle of an array
    • Change the original array
    • Returns the deleted array
    • delete
      • Pass two parameters
      • The first argument, the location of the first element to delete
      • The second argument deletes the number of elements
    • insert
      • Pass three or more parameters
      • The starting position of the first parameter
      • Second argument 0 (not deleted)
      • The third and above argument, the element to be inserted
    • replace
      • Pass three or more parameters
      • The starting position of the first parameter
      • The second parameter deletes the number
      • The third and above argument, the element to be inserted

12. Search and location methods

1. Strict equality

  • Both take two parameters, the element to look for, and the initial search location

  • Use === congruent comparison

  • IndexOf () returns the position in the array, -1 if not found

  • LastIndexOf () returns the position in the array, -1 if not found

  • Includes () returns a Boolean value indicating whether at least one match was found

2. Assert functions

  • Return matching information
  • The function takes three arguments, the element, the index, and the array itself
  • The assertion function returns a true value, indicating a match
  • find()
    • Start with the minimum index
    • Returns the first matched element
    • The second argument represents the value of the assertion function this
    • No more checking after a match is found
  • findIndex()
    • Minimum index start
    • Returns the first matching index
    • The second argument represents the value of the assertion function this
    • No more checking after a match is found

13. Iterative approach

  • Two parameters,

    • A function that takes each item as an argument
    • Optional scope object (this) that runs up and down as a function
  • The function passed to the method takes three arguments, the element, the index, and the array itself

  • Do not change the array from which they are called

  • Every () returns true if every function returns true

  • The filter() function returns true as an array

  • ForEach () runs forEach item and returns no value

  • Map () returns an array of the results of each function call

  • Some () returns true if one of the functions returns true

14. Merge method

  • Iterate over all the items in the array, building a final return value
  • Both receive two arguments
    • A merge function that runs on each of these terms
    • Optional initial value
  • The merge function takes four arguments, the last merge value, the current item, the current item index, and the entire array
  • The return value of the function is taken as the first argument of the next call
  • If there is no second argument, the first iteration starts with the second item of the array, the first parameter being the first item of the array, and the second parameter being the second item of the array.
  • reduce()
    • From the first term to the last term
  • reduceRight()
    • From the last term to the first term

3. Stereotype arrays

1, history,

  • Objective To make full use of 3D graphics API and GPU acceleration to render complex graphics on elements

1, WebGL

2. Stereotype arrays

  • CanvasFloatArray -> Float32Array

2, ArrayBuffer

3, DataView

4. Stereotype arrays

4, the Map

  • Map a new collection type, true key/value storage mechanism
  • Most features can be implemented using the Object type

1. Basic API

  • Const m = new Map()

  • Create simultaneous initializer instances that can be passed in an iterable. Each key/value pair in the iterable is inserted into the instance of the new map in iterative order.

    // Initialize the map with a nested array
    const m1 = new Map([["key1": "value1"],
      ["key2": "value2"],
      ["key3": "value3"]
    ])
    m1.size / / 3
    
    // Use custom iterators
    const m2 = new Map({[Symbol.iterator]: function* () {
        yield ["key1": "value1"];
        yield ["key2": "value2"];
        yield ["key3": "value3"];
      }
    })
    m2.size / / 3
    
    const m3 = new Map([[]])
    m3.has(undefined) // true
    m3.get(undefined) // undefined
    Copy the code
  • A Map can use any data type as a key, and using the SameValueZero comparison operation is basically equivalent to using strict object criteria to check key matches

  • Set () adds key/value pairs

    • Returns a mapping instance that can be concatenated
    • Object can only be a numeric, string, or Symbol key
  • Get () gets key/value pairs

  • Has () queries key/value pairs

  • Size Gets the number of key/value pairs

  • Delete () deletes key/value pairs

  • Clear () clears key/value pairs

  • 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 = {}
    const	objVal = {}
    const arrKey = []
    const arrVal = []
    
    m.set(objKey, objVal)
    m.set(arrKey, arrVal)
    
    objKey.foo = "foo"
    objVal.bar = "bar"
    arrKey.push("foo")
    arrVal.push("bar")
    m.get(objKey) // {bar: "bar"}
    m.get(arrKey) // ["bar"]
    Copy the code

2. Sequence and iteration

  • Map maintains the insertion order of key-value pairs and can perform iterative operations based on the insertion order

  • A mapping instance can provide an iterator that can generate an array of [key, value] in insertion order, which can be obtained through the entries() method (or the symbol.iterator property)

    const m = new Map([["key1": "val1"],
      ["key2": "val2"],
      ["key3": "val3"]
    ])
    m.entries === m[Symbol.iterator]
    
    for(let pair of m.entries()) {
      ...
    }
    for(let pair of m[Symbol.iterator]()){
     	...
    }
    // ["key1": "val1"],
    // ["key2": "val2"],
    // ["key3": "val3"]
    Copy the code
  • Since entries() is the default iterator, you can use extension operations directly on mapping instances

[...m]

  • Instead of iterators, you can use the mapped forEach(callback,opt_thisArg) method and pass in the callback to iterate over each key/value pair in turn. The callback passed in takes the second argument to override this

    const m = new Map([["key1": "val1"],
      ["key2": "val2"],
      ["key3": "val3"]
    ])
    m.forEach((val,key) = >alert(`${key} -> ${val}`))
    // key1 -> val1.Copy the code
  • Keys () and values() return iterators for the keys and values generated in insert order, respectively

    const m = new Map([["key1": "val1"],
      ["key2": "val2"],
      ["key3": "val3"]])for(let key of m.keys()){
      ...
    }
    for(let val of m.values()){
      ...
    }
    Copy the code
  • Keys and values can be modified during iterator traversal, but references inside the map cannot. You can modify internal properties that are key or value objects.

    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"
      m1.get("key1") // val1
    }
    
    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"
      key // {id: "newKey"}
    }
    ketObj // {id: "newKey"}
    
    // Same value.
    Copy the code

3. Select Object or Map

1. Memory usage

Given a fixed size of memory, Map stores approximately 50% more key-value pairs than Object

2. Insertion performance

Map is slightly faster, and Map performance is better for mass insertion operationsCopy the code

3. Search speed

  • There is very little performance difference between finding key-value pairs in large objects and maps
  • With only a small number of key-value pairs, Object can be faster
  • The browser engine optimizes using Object as an array (consecutive integers as properties).
  • Object is better when a lot of lookups are involved

4. Delete performance

  • Map delete() operations are faster than inserts and lookups
  • If a large number of delete operations are involved, select Map

5, WeakMap

  • “WeakMap”, weak refers to the way the JavaScript garbage collector treats the key in a “WeakMap”

1. Basic API

  • Initialize const wm = new WeakMap()

  • Weakly mapped keys can only be objects or types inherited from Objects

  • There is no restriction on the type of value

  • Populate weak maps at initialization time

    const key1 = {id: 1}
    const key2 = {id: 2}
    const key3 = {id: 3}
    
    const wm1 = new WeakMap([
      [key1, "val1"],
      [key2, "val2"],
      [key3, "val3"]
    ])
    vm1.get(key1) // "val1"
    vm1.get(key2) // "val2"
    vm1.get(key3) // "val3"
    
    // If only one key is invalid, the whole thing will fail
    const vm2 = new WeakMap([
      [key1, "val1"],
      ["BAD"."val2"],
      [key3, "val3"]])// The original value can be wrapped as an object before being used as a key
    const stringKey = new String("key1")
    const vm3 = new WeakMap([
      stringKey: "val1"
    ])
    Copy the code
  • Set () to add

  • The get ()

  • From the query ()

  • Delete () to delete

  • There is no clear ()

2, low key

  • Weak indicates that the weakly mapped key is “weakly held” and is not a formal reference and does not prevent garbage collection. But the median of 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.

    const wm = new WeakMap()
    wm.set({}, "val")
    Copy the code
    • The set() method initializes a new object and uses it as the key of the string
    • Since there are no other references to the object, the object key is garbage collected after execution.
    • The key-value pair disappears from the weak map and becomes an empty map.
    • Because the value is also not referenced, the value itself becomes a target for garbage collection when the key-value pair is destroyed.
    const wm = new WeakMap(a)const container = {
      key: {}
    }
    wm.set(container.key, "val")
    function removeReference() {
      container.key = null
    }
    Copy the code
    • The Container object holds a reference to this weakly mapped key, so it is not garbage collected.
    • But if a call to removeReference destroys the last reference, the garbage collection mechanism cleans up the key-value pair.

3. Non-iterable keys

  • Because key value pairs in WeakMap can be destroyed at any time
  • No iteration capability is provided
  • Do not use the clear() method
  • Restricting the use of objects as keys ensures that values can only be obtained through references to key objects. If raw values are used, there is no way to distinguish between a string literal used at initialization and an equal string used after initialization

4. Use weak mappings

1. Private variables

  • A new way to truly private variables. Private variables are stored in the weak map. Take the object as the key and the dictionary of the private member as the value.

    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)
    user.getId() / / 123
    user.setId(456) 
    user.getId() / / 456
    
    // But not really private
    wm.get(user)[user.idProperty] / / 456
    Copy the code
    • WeakMap is wrapped in a closure to be 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 propertyMembers = wm.get(this) || {}
          propertyMembers[property] = value
          wm.set(this, propertyMembers)
        }
        getPrivate(property) {
          return wm.get(this)[property]
        }
        setId(id) {
          this.setPrivate(this.idProperty, id)
        }
        getId() {
          return this.getPrivate(this.idProperty)
        }
      }
      return User
    })()
    
    const user = new User(123)
    user.getId() / / 123
    user.setId(456) 
    user.getId() / / 456
    Copy the code
    • This prevents the access mentioned earlier, and you fall completely into closure mode

2. DOM node metadata

  • WeakMap instances do not interfere with garbage collection and are suitable for storing associated metadata

    const wm = new WeakMap(a)const loginBtn = document.querySelector("#login")
    wm.set(loginBtn, {disabled: true})
    Copy the code
    • When a node is removed from the DOM tree, the garbage collector immediately frees its memory (not referenced elsewhere)

6, the Set

  • Collection type, more like enhanced Map.

1. Basic API

  • Create const m = new Set()

  • Create while initializing, you can pass in an iterable

    // Initialize the collection with an array
    const s1 = new Set(["val1"."val2"."val3"])
    s1.size / / 3
    
    // Initialize the collection with a custom iterator
    const s2 = new Set({[Symbol.iterator]: function* () {
        yield "val1";
        yield "val2";
        yield "val3";
      }
    })
    s2.size / / 3
    Copy the code
  • The added value of add() can be sequenced

  • From the () query value

  • Size gets the number of elements

  • Delete () deletes something

    • Returns a Boolean value indicating whether the collection contains the value to be deleted
  • Clear () deletes all

  • Sets can contain any data type as values, and collections are also operated with SameValueZero.

    const s = new Set(a)const functionVal = function() {}
    const symbolVal = Symbol(a)const objectVal = new Object()
    
    s.add(functionVal)
     .add(symbolVal)
     .add(objectVal)
    
    s.has(functionVal) // true
    s.has(symbolVal) // true
    s.has(objectVal) // true 
    
    // The SameValueZero check means that individual instances do not conflict
    s.has(function() {}) // false
    Copy the code
  • Objects used as values do not change when their own content or properties are modified

    const s = new Set(a)const objVal = {}
    const arrVal = []
    
    s.add(objVal).add(arrVal)
    
    objVal.bar = "bar"
    arrVal.push("bar")
    
    s.has(objVal) // true
    s.has(arrVal) // true
    Copy the code

2. Sequence and iteration

  • Set maintains the order in which values are inserted and supports sequential iteration

  • A collection instance provides an iterator that generates the contents of the collection in insertion order. This iterator can be obtained through the values() method and keys() or symbol.iterator property

    const s = new Set(["val1"."val2"."val3"])
    s.keys === s.va
    lues
    s.values === s[Symbol.iterator]
    for(let value of s.values()) {
      ...
    }
    for(let value of s[Symbol.iterator]()){
      ...
    }
    Copy the code
  • Values () is the default iterator and can be extended directly.

    const s = new Set(["val1"."val2"."val3"])
    [...s] // ["val1","val2","val3"]
    Copy the code
  • The entries() method returns an iterator

    const s = new Set(["val1"."val2"."val3"])
    
    for(let pair of s.entries()) {
    	pair 
      // ["val1","val1"]
      // ["val2","val2"]
      // ["val3","val3"]
    }
    Copy the code
  • ForEach () passes in a callback to iterate over each key-value pair

    const s = new Set(["val1"."val2"."val3"])
    
    s.forEach((val, dupVal) = > alert(`${val}->${dupVal}`))
    Copy the code
  • Changing the attributes of a value in a collection does not affect identity

    const s1 = new Set(["val1"])
    
    // The original string value cannot be modified as a value
    for(let value of s1.values()) {
      value = "newVal"
      s1.has("val1") // true
    }
    
    const valObj = {id: 1}
    const s2 = new Set([valObj])
    
    // Modify the properties of the value object, but the object is still in the collection
    for(let value of s2.values()) {
      value.id = "newVal"
      s2.has(valObj) // true
    }
    valObj // {id: "newVal"}
    Copy the code

3. Formally define collection operations

  • Subclass Set to define a library to use
  • Some Set operations are associative and ideally can support handling any number of collection instances
  • Set preserves the insertion order, and the collection returned by all methods must be ordered
  • Using memory as efficiently as possible and avoiding conversions between collections can save on object initialization costs
  • Do not modify existing collection instances (union(a,b)ora.union(b)Should return a new collection instance with the result.
class XSet extends Set {
	union(. sets) {
    return XSet.union(this. sets) }intersection(. sets) {
    return XSet.intersection(this. sets) }difference(set) {
    return XSet.difference(this, set)
  }
  
  symmetricDifference(set) {
    return XSet.symmetricDifference(this, set)
  }
  
  cartesianProduct(set) {
    return XSet.cartesianProduct(this, set)
  }
  
  powerSet() {
    return XSet.powerSet(this)}// Returns the union of two or more sets
  static union(a, ... bSets) {
    const unionSet = new XSet(a)
    for(const b of bSets) {
      for(const bValue of b) {
        unionSet.add(bValue)
      }
    }
    return unionSet
  }
  
  // Return the intersection of two more sets
  static intersection(a, ... bSets) {
    const intersectionSet = new XSet(a)
    for(const aValue of intersectionSet) {
      for(const b of bSets) {
        if(! b.has(aValue)) { intersectionSet.delete(aValue) } } }return intersectionSet
  }
  
  // Return the difference between two sets
  static difference(a, b) {
    const differenceSet = new XSet(a)
		for(const bValue of b) {
      if(a.has(bValue)) {
        differenceSet.delete(bValue)
      }
    }
    return differenceSet
  }
  
  // Return the symmetric difference between two sets
  static symmetricDifference(a, b) {
    return a.union(b).difference(a.intersection(b))
  }
  
  // Returns the cartesian product of two sets (array versus situation)
  // The set must be returned because the Cartesian product may contain pairs of the same value
  static cartesianProduct(a, b) {
    const cartesianProductSet = new XSet()
    for(const aValue of a) {
      for(const bValue of b) {
        cartesianProductSet.add([aValue, bValue])
      }
    }
    return cartesianProductSet
  }
  
  // Returns a set of powers
  static powerSet(a) {
    const powerSet = new XSet().add(new XSet())
    for(const aValue of a) {
      for(const set of new XSet(powerSet)) {
        powerSet.add(new XSet(set).add(aValue))
      }
    }
    return powerSet
  }
}
Copy the code

7, WeakSet

  • Weak collection, “weak” refers to the way the garbage collector treats the “weak collection” median

1. Basic API

  • Create const ws = new WeakSet()

  • The value of a weak set can only be Object or a type inherited from Object.

  • The weak collection is populated when initialized, and an iterable is received.

    const val1 = {id: 1}
    const val2 = {id: 2}
    const val3 = {id: 3}
    const ws1 = new WeakSet([val1, val2, val3])
    Copy the code
  • If one initialization fails, all fail

  • Raw values can be wrapped as objects to be used as values

  • Add () adds new values that can be concatenated

  • From the query ()

  • Delete () to delete

2, low value

  • In WeakSet, “weak” means that the value of weak set is “weak holding”, which will not prevent garbage collection
  • The same as the WeakMap

3. Non-iterable values

  • Can be destroyed at any time, no iteration capability
  • There is no clear() method
  • The purpose of limiting the use of objects as values is to ensure that values can be obtained only through references to objects. If you use raw values, there is no way to distinguish between a string literal used at initialization and an equal string used after initialization

4. Use weak sets

  • Label the object

    Set is tagged. If the DOM is removed but still in the collection, the garbage collection mechanism cannot reclaim it.

    // Set
    const disabledElements = new Set(a)const loginButton = document.querySector("#login")
    // Put a disable label on it
    disabledElements.add(loginButton)
    Copy the code

    WeakSet, the garbage collection program can pick it up.

8. Iteration and expansion

  • Iterators and extension operators are particularly useful for collection reference types, making it extremely easy to interoperate, copy, and modify collections.

    • Array
    • Finalize the design array
    • Map
    • Set
  • Both support sequential iteration and can be passed in 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)
      }
    }
    Copy the code
  • The extension operator is useful for shallow copies of iterable objects

    let arr1 = [1.2.3]
    let arr2 = [...arr1]
    arr1 === arr2 // false
    Copy the code
  • Expect iterable constructors that can be copied when passed in

    let map1 = new Map([[1.2], [3.4]])
    let map2 = new Map(map1)
    Copy the code
  • Build the array part parameters

    let arr1 = [1.2.3]
    let arr2 = [0. arr1,4.5]/ /,1,2,3,4,5 [0]
    Copy the code
  • Shallow copy copies only object references

    let arr1 = [{}]
    let arr2 = [...arr1]
    arr1[0].foo = "bar"
    arr2[0] // {foo: "bar"}
    Copy the code
  • With an Array of () Array. The from ()

    let arr1 = [1.2.3]
    
    // Copy the array to the stereotype array
    let typedArr1 = Int16Array.of(... arr1)let typedArr2 = Int16Array.from(arr1)
    
    // Array copy to map
    let map = new Map(arr1.map((x) = >[x, 'val' + x]))
    
    // Copy the array to the collection
    let set = new Set(typedArr2)
    
    // Sets copy arrays
    let arr2 = [...set]
    Copy the code