The default Iterator interface

The default Iterator interface is the Symbol. Iterator property deployed in a data structure, such as the Iterator interface:

let arr = ['a'.'b'.'c'];
let iter = arr[Symbol.iter])();

iter.next(); // { value: 'a', done: false }
iter.next(); // { value: 'b', done: false }
iter.next(); // { value: 'c', done: true }
Copy the code

Data structures native to Iterator include Array, Map, Set, String, TypeArray, function arguments, and NodeList objects. Other data structures need to deploy the Iterator interface to be for… The of loop traverses.

For array-like objects (with numeric keys and length attributes), you can deploy the symbol.iterator method by referring to the Iterator interface of the Array, or convert to an Array using the array.from () method:

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
/ / or
NodeList.prototype[Symbol.iterator] = [][Symbol.iterator];
/ / or
let arrayLike = { length: 2.0: 'a'.1: 'b' };
for (let x of Array.from(arrayLike)) {
    console.log(x); // 'a', 'b'
}

let iterable = {
    0: 'a'.1: 'b'.2: 'c'.length: 3[Symbol.iterator]: [][Symbol.iterator]
};
for (let item of iterable) {
    console.log(item); // 'a', 'b', 'c'
}

let iterable1 = {
    a: 'a'.b: 'b'.c: 'c'.length: 3[Symbol.iterator]: [][Symbol.iterator]
}
for (let item of iterable1) {
    console.log(item); // undefined, undefined, undefined
}
Copy the code

The symbol. iterator method for deploying arrays on ordinary objects has no effect.

If the symbol. Iterator method corresponds to something other than an ergoer generator (which returns an ergoer object), the interpretation engine will report an error.

var obj = {};

obj[Symbol.iterator] = () = > 1;

[...obj]; // Uncaught TypeError: Result of the Symbol.iterator method is not an object
Copy the code

Next (), return(), throw() of iterator objects

When deploying a traverser object, the next() method is mandatory, but the return() and throw() methods are not.

  • Next () : Next result of traverser execution
  • Return () : the for… The of loop exits prematurely (an error or a break or continue statement) and calls the return method, which must return an object.
  • Throw () : used mainly with Generator functions

for… In and for… Of the difference between

for… In and for… The difference between “of” and “forEach” : forEach cannot break out of a loop, for… In and for… Of can be used with break, continue, and return.

  1. for.. In can only get the key name of the object (array key name string “0”, “1”, “2”…) , for… Of gets the key value (keys() and entries() can be used to get the key name).
  2. for… In cannot use array keys(), values(), and entries() methods. For Set, the key name is the same as the key value; By default, the Map Iterator calls entries().)
  3. for… The of loop calls the iterator interface, and the array iterator interface returns only the value of the property with the key name numeric, for… In returns the key names of all attributes.
let arr = ['a'.'b'.'c'];

for (let a in arr) {
    console.log(a); / / 0, 1, 2
}

for (let a of arr) {
    console.log(a); // 'a', 'b', 'c'
}

for (let a in arr.entries()) {
    console.log(a); // undefined
}

for (let a of arr.entries()) {
    console.log(a); // [ 0, 'a' ], [ 1, 'b' ], [ 2, 'c' ]
}

arr.foo = "bar";
for (let a in arr) {
    console.log(a); // 0, 1, 2, foo
}
for (let a of arr) {
    console.log(a); // 'a', 'b', 'c'
}
Copy the code

Traversal of Set and Map structures

Notes for traversing Set and Map:

  • The traversal order is the order in which each member is added;
  • The Set structure returns a value, and the Map structure returns an array of the current key names and key values
let set = new Set(['a'.'b'.'c'.'a']);
for (let e of set) {
    console.log(e); // 'a', 'b', 'c'
}

let map = new Map().set("a".1).set("b".2);
for (let arr of map) {
    console.log(arr); // ['a', 1], ['b', 2]
}
Copy the code

Object traversal

For ordinary objects, for… Of cannot be used unless the Iterator interface is deployed, but for… In may be used to traverse key names.

You can use the object. keys method to generate an array of the Object’s key names and then iterate over the array.

let a = {
    a: 1.b: 2.c: 3
};
for (let item of a) {
    console.log(a); // Uncaught TypeError: a is not iterable
}
for (let item in a) {
    console.log(a); // a, b, c
}
for (let key of Object.keys(a)) {
    console.log(key + ':' a[key]); // a:1, b:2, c:3
}
Copy the code