JS data structures that represent collections include Array, Object, Map, and Set.

Requirements: A unified interface mechanism is required to traverse different data structures representing collections.

Solution: An Iterator is an interface that iterates over different data structures.

You don’t really use Iterator much in general projects, but understanding this might be the basis for understanding other things, like generators.

Iterator Iterator

The traverser object is essentially a pointer object (a pointer to think of traversing various structures).

(1) Create a pointer object that points to the starting position of the current data structure. .

(2) The first call to the next method of the pointer object can point to the first member of the data structure.

(3) The next call to the pointer object points to the second member of the data structure.

(4) Keep calling the next method of the pointer object until it points to the end of the data structure.

How to add an Iterator interface

Iterator is a function that returns the ** iterator **.

The iterator is essentially an object and has a next method that returns {value:xx,done:true/false}.

The value attribute returns the member of the current location, and the done attribute is a Boolean value indicating whether the traversal is complete, that is, whether it is necessary to call the next method again.

You can iterate through the data structure with “for of” and get the value each time.

var obj = {
  [Symbol.iterator]: function () {
    const keys = Object.keys(this)
    let p = 0
    return { next: () = > {
      const res = { value: this[keys[p]], done: keys.length < p + 1 }
      p++
      return res
    } }
  },
  a: 1.b: 2
}
let it = obj[Symbol.iterator]()
// An iterator is an object
console.log(it) // { next: [Function: next] }
console.log(it.next()) // { value: 1, done: false }
console.log(it.next()) // { value: 2, done: false }
console.log(it.next()) // { value: undefined, done: true }

for (let v of obj) {
  // As above, output twice, 1, 2
  console.log(v)
}

Copy the code

You can also add Iterator interfaces using generators

When the generator executes, it returns the traverser instance directly.

var obj = {
  [Symbol.iterator]: function *  () {
    yield 1
    yield 2
  },
  a: 1.b: 2
}
let it = obj[Symbol.iterator]()
console.log(it) // Object [Generator] {}
console.log(it.next()) // { value: 1, done: false }
console.log(it.next()) // { value: 2, done: false }
console.log(it.next()) // { value: undefined, done: true }

for (let v of obj) {
  // As above, output twice, 1, 2
  console.log(v)
}
Copy the code

A data structure that inherently has an Iterator interface

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • The arguments object for the function
  • The NodeList object

Attention!! Objects have no built-in Iterator interface, so you can’t use for traversal unless you add them manually

Use an array as an example:

var arr = [1.2]
let it = arr[Symbol.iterator]()
console.log(it) // { next: [Function: next] }
console.log(it.next()) // { value: 1, done: false }
console.log(it.next()) // { value: 2, done: false }
console.log(it.next()) // { value: undefined, done: true }

for (let v of arr) {
  // As above, output twice, 1, 2
  console.log(v)
}

Copy the code

The usage scenario of the traverser

  • deconstruction
  • Extended operator
  • Because array traversal calls the traverser interface, any situation that takes an array as an argument actually calls the traverser interface
    • for… of
    • Array.from()
    • The Map () and Set (), WeakMap (), WeakSet () (such as a new Map ([[‘ a ‘, 1], [‘ b ‘, 2]]))
    • Promise.all()
    • Promise.race()

Comparison with other traversal syntax

Take the traversal number group as an example:

  • for: Tedious
  • forEach: Cannot break out of the forEach loop
  • for in: Iterates through the key names (indexes) of the array, as well as the keys on the prototype chain. Of course, it’s for traversing objects in general

Advantages of for of:

  • With withfor... inSame concise syntax, but the output is yesThe currentThe value of the key.
  • canBreak, continue and returnUse together.
  • Provides a unified operation interface for traversing all data structures.

Note that the object cannot use for of directly because there is no built-in Iterator.

reference

-Ruan Yifeng’s ES6 manual

This article is basically a summary of this page, so do not understand, you can brush this page.