"Code tailor" provides technical-related information and a series of basic articles for front-end developers. Follow the "Novices of Xiaohe Mountain" public account on WeChat to get the latest articles in time.
Preface
Before starting to learn, what we want to tell you is that this article is "Iterator" chapter in Ruan Yifeng's "Introduction to ECMAScript6" book. If you have mastered the following knowledge items, you can skip this link directly Go to exercise
- What is Iterator? What's the effect?
- How does iterator traverse?
- What are the default Iterator interfaces and common occasions?
If you have forgotten some parts, 👇🏻 is ready for you!
Learning link
Summary
Concept and function
JavaScript
represents the data structure of "collections", mainly arrays ( Array
), objects ( Object
), Map
and Set
. The user can use them in combination, define its own data structures, such as members of the array are Map
, Map
members objects. This requires a unified interface mechanism to handle all different data structures.
The iterator (Iterator
) is such a mechanism. It is an interface that provides a unified access mechanism for a variety of different data structures. As long as any data structure deploys theIterator
interface, the traversal operation can be completed (that is, all members of the data structure are processed in turn).
effect:
- Provide a unified and simple access interface for various data structures
- So that the members of the data structure can be arranged in a certain order
- ES6 has created a new traversal command
for...of
loop. The Iterator interface is mainly used forfor...of
to traverse loops.
Traversal process
- Create a pointer object that points to the starting position of the current data structure. In other words, the iterator object is essentially a pointer object.
- The first time you call the
next
method of the pointer object, you can point the pointer 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. - Keep calling the
next
method of the pointer object until it points to the end of the data structure.
Default Iterator interface
Iterator
interface is to provide a unified access mechanism for all data structures, that is, the for...of
cycle. When using for...of
loop through a certain data structure, the loop will automatically find the Iterator
interface. As long as a data structure is deployed with the Iterator
interface, we call this data structure "traversable".
In ES6, the following data structures have the native Iterator
interface, that is to say, these data structures can be traversed for...of
- Array
- Map
- Set
- String
- TypedArray
- The arguments object of the function
- NodeList object
In addition to the above data structures, if you need to call for...of
Object
), you need to Symbol.iterator
attribute, so that it will be traversed for...of
Examples of definition methods are as follows:
const obj = {
[Symbol.iterator]: function () {
return {
next: function () {
return {
value: 1,
done: true,
}
},
}
},
}
Common occasions for calling Iterator
- Destructuring 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']
- Spread operator
// 例一
var str = 'hello'
[...str] // ['h','e','l','l','o']
// 例二
let arr = ['b', 'c']
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']
- 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 }
Understand how to write a traverser
In addition to thenext()
method, the iterator object can also have thereturn()
method andthrow()
method. If you write your own traverser object generation function, then thenext()
method must be deployed,return()
method andthrow()
method are deployed is optional.
/*
return()方法的使用场合是,如果for...of循环提前退出(通常是
因为出错,或者有break语句),就会调用return()方法。如果一个对
象在完成遍历前,需要清理或释放资源,就可以部署return()方法。
*/
function readLinesSync(file) {
return {
[Symbol.iterator]() {
return {
next() {
return { done: false }
},
return() {
file.close()
return { done: true }
},
}
},
}
}
Self-test
1: The difference between for in and for of
2: What will the following code output ()
const obj = { 2: 5, 3: 6, 4: 7 }
obj[Symbol.iterator] = function () {
return {
next: function () {
if (this._countDown === 3) {
return { value: this._countDown, done: true }
}
this._countDown = this._countDown + 1
return { value: obj[this._countDown], done: false }
},
_countDown: 0,
}
}
for (const i of obj) {
console.log(i)
}
- A.
2,3,4
- B.
5,6,7
- C.
undefined
,5
,6
- D.
TypeError: obj is not iterable
Problem analysis
One,
Answer:
correct answer and analysis:
for...in | for...of | |
---|---|---|
Applies to | Enumerable Properties | Iterable Collections |
Use with Objects? | Yes | No |
Use with Arrays? | Yes, but not advised | Yes |
Use with Strings? | Yes, but not advised | Yes |
two,
Answer:(C)
obj is a normal object, such as D being given normal traverse, but the above code added Symbol.iterator
properties, can be traversed, traversing viewed return
value obj[this._countDown]
, and the number of times each traversal key name as the value to be seen , Obj only has the three keys of 2, 3, 4, so the first time I get undefined, I get 5 and 6 later, so choose C
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。