이 글에서는 반복자와 관련된 문제를 주로 소개하는 javascript에 대한 관련 지식을 제공합니다. 반복이란 데이터 세트에서 특정 순서로 지속적으로 데이터를 추출하는 프로세스에 대해 함께 이야기해 보도록 하겠습니다. 모든 사람.
[관련 권장 사항: javascript 비디오 튜토리얼, web front-end]
Iteration은 데이터 세트에서 특정 순서에 따라 지속적으로 데이터를 추출하는 프로세스를 의미합니다.
그럼 반복과 순회의 차이점은 무엇인가요?
JavaScript에서 반복자는 를 다음으로 호출할 수 있습니다. /code> 메소드는 반복되는 객체를 구현하고, 이 메소드는 두 가지 속성을 가진 객체를 반환합니다. <code> next
方法实现迭代的一个对象,该方法返回一个具有两个属性的对象。
value
:可迭代对象的下一个值 done
:表示是否已经取出所有的数据了。 false
表示还有数据, true
表示后面已经没有数据了。通过可迭代对象中的迭代器工厂函数 Symbol.iterator
来生成迭代器。
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())
可以发现,迭代器是取完最后一个值之后,即迭代器下一个值 value
为 undefined
时,完成。
但是,上面的说法并不是很准确,并不是迭代器下一个值 value
为 undefined
时,就完成的。还需要判断是不是真的没有值,还是是可迭代对象里就有一个值为 undefined
。如果是可迭代对象里有一个值为 undefined
的情况,那么此时还是不会变成完成状态。
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())
可以多次调用迭代器工厂函数来生成多个迭代器,每个迭代器都表示对可迭代对象的一次性有序遍历。不同迭代器之间互不干扰,只会独立地遍历可迭代对象。
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 }
如果可迭代对象在迭代期间被修改了,迭代器得到的结果也会是修改后的。
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())
当我们迭代到 done: true
之后,再调用next
是不是会报错,或者不返回任何内容呢?
然而,并不是,迭代器会处于一种完成但并不完成的状态, done: true
表示已经完成了,但是后续还能一直调用 next
,虽然得到的结果一直都会是 { value: undefined, done: true }
。这就是为什么说完成但并不完成。
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())
从上面的例子中,我们就可以知道是通过通过迭代器工厂函数 Symbol.iterator
来生成迭代器,所以我们需要实现一个迭代器迭代器工厂函数,然后迭代器可以调用 next
方法,所以还需要实现一个 next
方法,至于迭代器工厂函数,实际上直接返回实例 this
。
计数器例子:
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())
乍一看,没啥问题,但是如果我们使用 for-of
value
: 반복 가능한 객체의 다음 값
done
: 모든 데이터를 꺼냈는지 여부를 나타냅니다. false
는 아직 데이터가 있음을 의미하고, true
는 나중에 데이터가 없음을 의미합니다. 🎜🎜Symbol.iterator
를 통해 반복자를 생성합니다. 🎜const counter = new Counter(3)for (let i of counter) { console.log(i)}console.log('另一轮迭代:')for (let i of counter) { console.log(i)}
class Counter { constructor(limit) { this.limit = limit } [Symbol.iterator]() { let count = 1 const limit = this.limit return { // 迭代器工厂函数必须要要返回一个带有next方法的对象,因为迭代实际就是通过调用next方法来实现的 next() { if (count 🎜<img rc="https://img.php.cn/upload/article/000/000/067/b0f4b9ec88bed8d7314f0d02979e4f22-1.png" alt="JavaScript 반복자 지식 포인트 요약">🎜🎜반복자 🎜가 다음의 마지막 것임을 알 수 있습니다 가져오기 🎜 값 이후, 즉 반복자 <code> 값</code>의 다음 값이 <code> 정의되지 않음</code>이면 완료됩니다. 🎜🎜그러나 위의 문장은 반복자 <code> 값</code>의 다음 값이 <code> 정의되지 않음</code>인 경우에는 매우 정확하지 않습니다. 또한 실제로 값이 없는지 또는 반복 가능한 객체에 <code> 정의되지 않은</code> 값이 있는지 확인해야 합니다. 반복 가능한 객체에 <code> 정의되지 않은</code> 값이 있으면 지금은 완료되지 않습니다. 🎜<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)}
[Symbol.iterator]() { let count = 1 const limit = this.limit return { // 迭代器工厂函数必须要要返回一个带有next方法的对象,因为迭代实际就是通过调用next方法来实现的 next() { if (count 🎜<img src="https://img.php.cn/upload/article/000/000/067/6e653883231363b12bbca2ffd8df90bf-3.png" alt="JavaScript 반복자 지식 포인트 요약">🎜<h2>반복자 객체 Can 반복 가능한 객체로 사용됩니다.</h2><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)}
done: true
로 반복하면 오류가 보고되나요, 아니면 next
를 호출할 때 아무것도 반환되지 않나요? 🎜🎜그러나 아니요, 반복자는 🎜완료되었지만 완료되지 않은 상태입니다🎜. done: true
는 완료되었지만 여전히 next
를 호출할 수 있음을 의미합니다. future.code>이지만 결과는 항상 { value: unundefined, done: true }
입니다. 그렇기 때문에 🎜완료되었지만 완료되지 않았습니다🎜라고 합니다. 🎜rrreee🎜🎜 Symbol.iterator
를 통해 생성된다는 것을 알 수 있으므로 iterator iterator 팩토리 함수를 구현한 다음 iterator를 구현해야 합니다. next
메서드를 호출할 수 있으므로 next
메서드도 구현해야 합니다. 반복자 팩토리 함수의 경우 실제로 this
인스턴스를 반환합니다. 직접. >. 🎜🎜카운터 예: 🎜rrreeerrreee🎜 🎜🎜 얼핏 보면 문제가 없지만 for-of
를 이용하여 순회하면 문제를 찾을 수 있습니다. 🎜rrreee🎜🎜🎜使用 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前端】
위 내용은 JavaScript 반복자 지식 포인트 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!