This article brings you relevant knowledge about javascript, which mainly introduces related issues about iterators. Iteration means that data can be continuously taken out from a data set in a certain order. Let’s take a look at the process below. I hope it will be helpful to everyone.
[Related recommendations: javascript video tutorial, web front-end]
Iteration means that you can start from one Dataset is the process of continuously extracting data in a certain order.
So what is the difference between iteration and traversal?
In JavaScript, an iterator is an object that can call the next
method to implement iteration, which returns an object with two properties.
value
: The next value of the iterable object done
: Indicates whether all the data has been taken out. false
means there is still data, true
means there is no data later. Generate iterators through the iterator factory function Symbol.iterator
in the iterable object.
const arr = []console.log(arr)
const arr = [1, 2, 3] const iter1 = arr[Symbol.iterator]() // 通过迭代器工厂函数` Symbol.iterator`来生成迭代器。 console.log(iter1) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log('%c%s', 'color:red;font-size:24px;', '================') const mymap = new Map() mymap.set('name', 'clz') mymap.set('age', 21) const iter2 = mymap[Symbol.iterator]() // 通过迭代器工厂函数` Symbol.iterator`来生成迭代器。 console.log(iter2) console.log(iter2.next()) console.log(iter2.next()) console.log(iter2.next())
It can be found that the iterator is after taking the last value of , that is, the next iterator Completed when value value
is undefined
.
However, the above statement is not very accurate. It is not completed when the next value of the iterator value
is undefined
. You also need to determine whether there is really no value, or whether there is a value undefined
in the iterable object. If there is a value in the iterable object that is undefined
, then it will not become completed at this time.
const arr = [1, 2, 3, undefined] const iter1 = arr[Symbol.iterator]() // 通过迭代器工厂函数` Symbol.iterator`来生成迭代器。 console.log(iter1) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next())
You can call the iterator factory function multiple times to generate multiple iterators, each iterator Represents a one-time ordered traversal of an iterable object. Different iterators do not interfere with each other and will only traverse iterable objects independently.
const arr = [1, 2, 3] const iter1 = arr[Symbol.iterator]() // 通过迭代器工厂函数` Symbol.iterator`来生成迭代器。 const iter2 = arr[Symbol.iterator]() console.log('迭代器1:', iter1.next()) console.log('迭代器2:', iter2.next()) console.log('迭代器1:', iter1.next()) console.log('迭代器2:', iter2.next())
const arr = [1, 2, 3] const iter = arr[Symbol.iterator]() for (const i of iter) { console.log(i) // 依次输出1、2、3 }
If the iterable object is in If it is modified during iteration, the result obtained by the iterator will also be modified.
const arr = [1, 2, 3] console.log(arr) const iter = arr[Symbol.iterator]() console.log(iter.next()) arr[1] = 999 console.log(iter.next()) console.log(iter.next())
When we iterate to done: true
, then call next
Will it report an error or not return any content?
However, no, the iterator will be in a state of completed but not completed, done: true
means it has been completed, but it can continue Call next
, although the result will always be { value: undefined, done: true }
. That's why it's said that is done but it's not done .
const arr = [1, 2, 3] const iter = arr[Symbol.iterator]() console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next())
From the above example, we can know that it is passed through the iterator factory function Symbol .iterator
to generate iterator, so we need to implement an iterator iterator factory function, and then the iterator can call the next
method, so we also need to implement a next
Method, as for the iterator factory function, it actually returns the instance this
directly.
Counter example:
class Counter { constructor(limit) { this.count = 1 this.limit = limit } next() { if (this.count <pre class="brush:php;toolbar:false">const counter = new Counter(3) const iter = counter[Symbol.iterator]() console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next())
At first glance, there is no problem, but if we use for-of
to traverse problem found.
const counter = new Counter(3)for (let i of counter) { console.log(i)}console.log('另一轮迭代:')for (let i of counter) { console.log(i)}
使用 for-of
循环也变成一次性的了。这是因为 count
是该实例的变量,所以两次迭代都是使用的那一个变量,但是该变量第一次循环完之后,就已经超过限制了,所以再次使用 for-of
循环就得不到任何的结果了。
可以把 count
变量放在闭包里,然后通过闭包返回迭代器,这样子每创建一个迭代器都会对应一个新的计数器。
class Counter { constructor(limit) { this.limit = limit } [Symbol.iterator]() { let count = 1 const limit = this.limit return { // 迭代器工厂函数必须要要返回一个带有next方法的对象,因为迭代实际就是通过调用next方法来实现的 next() { if (count <p>测试</p><pre class="brush:php;toolbar:false">const counter = new Counter(3)for (let i of counter) { console.log(i)}console.log('另一轮迭代:')for (let i of counter) { console.log(i)}
就和使用 for-of
循环一样,迭代器会很聪明地去调用 next
方法,当迭代器提前终止时,它也会去调用 return
方法。
[Symbol.iterator]() { let count = 1 const limit = this.limit return { // 迭代器工厂函数必须要要返回一个带有next方法的对象,因为迭代实际就是通过调用next方法来实现的 next() { if (count <p>测试</p><pre class="brush:php;toolbar:false">const counter = new Counter(5)for (let i of counter) { if (i === 3) { break; } console.log(i)}
如果迭代器没有关闭,就可以继续从上次离开的地方继续迭代。数组地迭代器就是不能关闭的。
const arr = [1, 2, 3, 4, 5]const iter = arr[Symbol.iterator]()iter.return = function () { console.log('提前退出迭代器') return { done: true }}for (const i of iter) { console.log(i) if (i === 2) { break }}for (const i of iter) { console.log(i)}
【相关推荐:javascript视频教程、web前端】
The above is the detailed content of Summary of JavaScript iterator knowledge points. For more information, please follow other related articles on the PHP Chinese website!