In ES6, Map and Set are added to JavaScript’s original data structures that represent “collections”, mainly arrays and objects

An Iterator is one such mechanism. It is an interface that provides a unified access mechanism for various data structures. The Iterator interface can be deployed on any data structure to complete traversal (that is, processing all members of the data structure in turn).

Iterator does three things:

One is to provide a unified and simple access interface for various data structures.

Second, the members of the data structure can be arranged in a certain order.

Third, ES6 created a new traversal command for… The of loop is an Iterator interface for… Of consumption

Traversal process

  1. Creates a pointer object that points to the start of the current data structure. That is, the traverser object is essentially a pointer object
  2. The first time a pointer object is callednextMethod to point to the first member of a data structure
  3. The second call to the pointer objectnextMethod, which points to the second member of the data structure
  4. That constantly calls the pointer objectnextMethod until it points to the end of the data structure
var it = makeIterator(['a'.'b']);
it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }
function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++], done: false}, {value: undefined.done: true}; }}; }Copy the code

The next method of a pointer object, used to move the pointer. At the beginning, the pointer points to the beginning of the array. Then, each time the next method is called, the pointer points to the next member of the array. First call, point to a; The second call, to b

The next method returns an object representing information about the current data member. This object has two properties, value and done. The value property returns the member of the current position, and the done property is a Boolean value indicating whether the traversal is complete, that is, whether it is necessary to call the next method again.

An example of a traverser object that runs indefinitely

var it = idMaker();
it.next().value / / 0
it.next().value / / 1
it.next().value / / 2
// ...
function idMaker() {
  var index = 0;
  return {
    next: function() {
      return {value: index++, done: false}; }}; }Copy the code

TS

interface Iterable {
  [Symbol.iterator]() : Iterator,
}
interfaceIterator { next(value? :any) : IterationResult,
}
interface IterationResult {
  value: any.done: boolean,}Copy the code

The default Iterator interface

A data structure is said to be “iterable” whenever the Iterator interface is deployed.

The ymbol.iterator property is itself a function, which is the default traverser generator for the current data structure

const obj = {
  [Symbol.iterator] : function () {
    return {
      next: function () {
        return {
          value: 1.done: true}; }}; }};Copy the code

Some ES6 data structures have native Iterator interfaces (such as arrays) that can be used for… The of loop traverses

The reason is that these data structures have symbol.iterator attributes deployed natively (see below), while others (such as objects) do not. Any data structure that deploys the symbol. iterator property is said to have deployed the traverser interface

The data structures with the native Iterator interface are as follows.

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

The context in which the Iterator interface is called

In addition to… Of loops, and a couple of other occasions.

(1) Deconstructing assignment

let set = new Set().add('a').add('b').add('c');
let [x,y] = set;
// x='a'; y='b'
let [first, ...rest] = set;
// first='a'; rest=['b','c'];
Copy the code

(2) Extended operators

Extended operators (…) The default Iterator interface is also called.

/ / a
var str = 'hello';
[...str] // ['h','e','l','l','o']
/ / two cases
let arr = ['b'.'c'];
['a'. arr,'d']
// ['a', 'b', 'c', 'd']
Copy the code

(3) the yield *

let generator = function* () {
  yield 1;
  yield* [2.3.4];
  yield 5;
};
var iterator = generator();
iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }
Copy the code

(4) Other occasions

Because array traversal calls the traverser interface, any situation that takes an array as an argument actually calls the traverser interface. Here are some examples.

  • The for… of
  • Array.from()
  • WeakMap(), Set(), WeakMap(), WeakSet() (e.gnew Map([['a',1],['b',2]]))
  • Promise.all()
  • Promise.race()

Iterator interface for strings

A string is an array-like object that also natively has an Iterator interface.

var someString = "hi";
typeof someString[Symbol.iterator]
// "function"
var iterator = someString[Symbol.iterator]();
iterator.next()  // { value: "h", done: false }
iterator.next()  // { value: "i", done: false }
iterator.next()  // { value: undefined, done: true }
Copy the code