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
- Creates a pointer object that points to the start of the current data structure. That is, the traverser object is essentially a pointer object
- The first time a pointer object is called
next
Method to point to the first member of a data structure - The second call to the pointer object
next
Method, which points to the second member of the data structure - That constantly calls the pointer object
next
Method 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.g
new 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