1. Origin and significance
Javascript
Indicating "set" data structure, mainly Array
, Object
, Map
, Set
four data sets, in addition, also be combined with each other between them, for example Array
the members Map
, Map
the members Object
and the like. Therefore Javascript
, a unified interface mechanism is needed to handle all different data structures.
The iterator ( Iterator
) is such a mechanism. It is an interface that can provide an access mechanism (access interface) for various data structures. Any data structure deployment Iterator
interface can complete the traversal operation of the data deconstructor (Iterator interface is mainly for for...of
use).
Second, the specific implementation process
Iterator
The traversal process:
- Create a pointer object that points to the starting position of data deconstruction.
- The method of the pointer object is called for the first time
next()
, and the pointer points to the first member of the data structure. - The second call to the
next()
method of the pointer object , the pointer points to the second member of the data structure. - Call the
next()
method of the pointer object until it points to the end of the data structure. (Similar to the linked list in C language)
Each time the next
method is called , the information of the member pointed to by the pointer in the data structure is returned. The information is an object, which contains objects value
with done
two attributes { value: something , done: false }
. The value
attribute is the value of the current member, and the done
attribute is a boolean value indicating whether the traversal is over ( done:false
: indicates that the loop is not over yet,: done:true
indicates that the loop is over).
next
Examples of simulation method return values:
The following code defines a makeIterator
function, it is a traverser generating function, the role is to return a traverser object. ['前端','收割','机']
Executing this function on an array will return the iterator object (pointer object) of the array goodjob
.
var goodjob = makeIterator(['前端','收割','机'])
function makeIterator(array){
var Index = 0;//形成闭包保存指针指向位置index,通过三元表达式返回当前信息对象。
return {
next: function(){
return Index < array.length ? {
value: array[index], done: false} :
{
value: undefined, done: true};
}
}
}
goodjob.next()// {value: '前端', done: false}
goodjob.next()// {value: '收割', done: false}
goodjob.next()// {value: '机', done: false}
goodjob.next()// {value: undefined, done: false}
Since Iterator
only the specifications of the interface is added to the data structure above, therefore, that it traverses the data structure with which it is traversed, physically separate, can not traverse the object corresponding to the write data structure, or object with the traverse Simulate the data structure.
Three, the data structure with the default Iterator interface
Iterator
Purpose interface for all data structures that provides a unified access mechanism, when for...of
the time loop through some kind of data structure, the cycle will automatically look for Iterator
the interface.
Therefore, when a certain data structure has an Iterator
interface, it means that the data structure is traversable ( iterable
).
The default Iterator
interface to be deployed in the data structure of the Symbol.iterator
property, or that has a data structure as long as the Symbol.iterator
property can be considered to be "traversed" ( iterable
). Symbol.iterator
The attribute itself is a function, which is the default traverser generating function of the current data structure. Executing this function will return a iterator. As for the attribute name Symbol.iterator
, it is an expression that returns Symbol
an object of iterator
property, which is a pre-defined type is Symbol
of special value, it should be placed within square brackets.
const object1 = {
[Symbol.iterator] : function () {
return {
next: function () {
return {
value: 1,
done: true
};
}
};
}
};
Objects object1
are traversable ( iterable
) because they have Symbol.iterator
attributes. Executing this property will return a iterator object. The fundamental characteristic of this object is its next
method. Each time the next
method is called , an information object representing the current member will be returned, with two attributes value
and sum done
.
Any Symbol.iterator
data structure with attributes deployed is called a traverser interface deployed. Calling this interface will return a traverser object. That is, it can be for...of
looped through without any processing .
Native data structure with Iterator interface:
- Array
- Map
- Set
- String
- TypedArray
- NodeList object
- The arguments object of the function
Symbol.iterator
Attributes of the array :
let arr = ['前端', '收割', '机'];
let iterator = arr[Symbol.iterator](); //因为arr中属性Symbol.iterator返回的是一个函数,
//所以在[Symbol.iterator]后面添加(),使函数执行,返回一个遍历器对象
iterator.next() // { value: '前端', done: false }
iterator.next() // { value: '收割', done: false }
iterator.next() // { value: '机', done: false }
iterator.next() // { value: undefined, done: true }
Array iterator generated by for of
calling the iterator
interface
const arr = ['前端', '收割', '机'];
for(let v of arr) {
console.log(v); // 前端 收割 机
}
Map traverser generated by for of
calling the iterator
interface
var handsome = new Map();
es6.set("GuangHui", "1handsome");
es6.set("JiaHao", "2handsome");
es6.set("NingDong", 666);
for (var [name, value] of es6) {
console.log(name + ": " + value);
}
// GuangHui: 1handsome
// JiaHao: 2handsome
// NingDong: 666
Set iterator generated by for of
calling the iterator
interface
var handsome = new Set(["GuangHui", "JiaHao", "NingDong"]);
for (var boy of handsome) {
console.log(boy);
}
// GuangHui
// JiaHao
// NingDong
The iterator generated by for of
calling the iterator
interface of an array-like object
// 字符串
let str = "前端收割机";
for (let s of str) {
console.log(s); // 前 端 收 割 机
}
// DOM NodeList对象
let paras = document.querySelectorAll("p");
for (let p of paras) {
p.classList.add("前端收割机");
}
// arguments对象
function printArgs() {
for (let x of arguments) {
console.log(x);
}
}
printArgs('前端', '收割机');
// '前端'
// '收割机'
For Iterator
data structures (mainly objects) that do not have interfaces, they need to be Symbol.iterator
deployed on the properties themselves so that they can be for...of
traversed in a loop.
Cause: Object ( Object
) is no reason why the default deployment Iterator
interfaces, because of which traverse the properties of the object first, after which traverse the property is uncertain, developers need to manually specify. Essentially, the traverser is a linear process. For any non-linear data structure, deploying the traverser interface is equivalent to deploying a linear transformation.
Here the object is added as Iterator
an example of the interface:
let object2 = {
data: [ '前端', '收割','机'],
[Symbol.iterator]() {
const self = this; //将this指向赋予self
let index = 0; //初始遍历下标
return {
next() {
if (index < self.data.length) {
return {
value: self.data[index++], //每次调用,遍历下标自增1
done: false
};
} else {
return { value: undefined, done: true }; //遍历结束返回该对象
}
}
};
}
};
For array-like objects (keys and values exist length
attributes), deployed Iterator interface, there is a simple method, it is Symbol.iterator
the method of direct reference to the array Iterator
interface.
let object3 = {
0: '前端',
1: '收割',
2: '机',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator] //直接引用数组构造函数prototype中的 Symbol.iterator属性
};
for (let item of iterable) {
console.log(item); // '前端', '收割', '机'
}
Note that the Symbol.iterator
method of deploying a specific data structure for ordinary objects has no effect. For example, the Symbol.iterator
method of deploying an array of ordinary objects .
let object4 = {
//该对象不存在数值键名
a: '前端',
b: '收割',
c: '机',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // undefined, undefined, undefined
}
If the Symbol.iterator
method does not correspond to a traverser generating function (that is, it returns a traverser object), the interpretation engine will report an error.
var object5 = {};
obj[Symbol.iterator] = () => '前端收割机'; //返回的是一个字符串
[...object5] // TypeError: [] is not a function
Fourth, the occasion to call the Iterator interface
In addition to for...of
recycling, some scenes will be called by default Iterator
interfaces (ie Symbol.iterator
method)
Destructuring assignment
let set = new Set().add('前端').add('收割').add('机'); //Set通过add方法进行链式添加值
let [one,two] = set;
// x='前端'; y='收割'
let [one, ...two] = set;
// one='前端'; two=['收割','机'];
Spread operator
// 例一
var str = '前端收割机';
[...str] // ['前','端','收','割','机']
// 例二
let arr = ['是', '靓'];
['我', ...arr, '仔']
// ['我', '是', '靓', '仔']
Extended internal operator calls the Iterator
interface, which provides a simple mechanism, it can be deployed to any Iterator
interface data structure, by extending the operator, into an array.
yield*
yield*
What follows is a traversable structure, which will call the traverser interface of the structure.
let generator = function* () {
yield "我";
yield* ["是","靓","仔"];
yield "啊";
};
var iterator = generator();
iterator.next() // { value: "我", done: false }
iterator.next() // { value: "是", done: false }
iterator.next() // { value: "靓", done: false }
iterator.next() // { value: "仔", done: false }
iterator.next() // { value: "啊", done: false }
iterator.next() // { value: undefined, done: true }
Array.from()
Array.from()
Input the value to the function in the form of an array, and the Array.from()
function calls the Iterator interface to convert the input array into an array
let arrayLike = {
0: '前端',
1: '收割',
2: '机',
3: ['GuangHui','JiaHao','NingDong'],
'length': 4
}
let arr = Array.from(arrayLike)
console.log(arr) // ['前端','收割','机',['GuangHui','JiaHao','NingDong']]
Map(), Set(), WeakMap(), WeakSet()
Map
Enter key-value pairs into the constructor in the form of an array. When creating an Map
object, the Map constructor calls the Iterator
interface, traverses and saves the key-value pairs
var goodJob = new Map([['前端',1],['收割机',2]])
Promise.all()
Promise.all()
Enter the value in the form of a Promise array to the function, and the Promise.all()
function calls the Iterator interface to traverse and execute the promise request.
const p = Promise.all([p1, p2, p3]);
Promise.all()
Method accepts an array as a parameter p1
, p2
, p3
it is Promise
an example, if not, it will first call the Promise.resolve
method parameters into the Promise
instance, and then further processing. Further, Promise.all()
parameters of the method may not be an array, but it must have Iterator
an interface, and each member is returned Promise
instance.
Promise.race()
Promise.race()
Enter the value in the form of a Promise array to the function, and the Promise.race()
function calls the Iterator interface to traverse and execute the promise request.
const p = Promise.race([p1, p2, p3]);
Promise.race()
Method accepts an array as a parameter p1
, p2
, p3
it is Promise
an example, if not, it will first call the Promise.resolve
method parameters into the Promise
instance, and then further processing. Further, Promise.race()
parameters of the method may not be an array, but it must have Iterator
an interface, and each member is returned Promise
instance.
Added: Generator
function and Iterator
relationship interface:
The Symbol.iterator
method of the object is equal to the traverser generating function of the object, and calling this function will return a traverser object of the object. Since the Generator function is the traverser generating function, the Generator can be assigned to the Symbol.iterator
properties of the object, so that the object has the Iterator interface.
Five, summary
- The iterator (
Iterator
) can provide an access mechanism (access interface) for various data structures. Any data structure deploymentIterator
interface can complete the traversal operation of the data deconstructor (Iterator interface is mainly forfor...of
use). Iterator
The traversal process: Create a pointer object that points to the starting position of data deconstruction. Thenext()
method of the pointer object is continuously called , and the pointer moves backward until it points to the end of the data structure. Each time thenext
method is called , the information of the member pointed to by the pointer in the data structure is returned{ value: something , done: false }
.Array
,Map
,Set
,String
,TypedArray
,NodeLis
T objects, functionarguments
objects on native includesIterator
a data structure of the interface.- Call
Iterator
interface occasions:for...of
cycle, destructuring assignment, expansionyield*
operators,Array.from()
,Map()
,Set()
,WeakMap()
,WeakSet()
,Promise.all()
,Promise.race()
, .