首頁 > web前端 > js教程 > 主體

JavaScript迭代器知識點總結

WBOY
發布: 2022-06-15 12:00:39
轉載
1725 人瀏覽過

本篇文章為大家帶來了關於javascript的相關知識,其中主要介紹了關於迭代器的相關問題,迭代就是指可以從一個數據集中按照一定的順序,不斷取出數據的過程,下面一起來看一下,希望對大家有幫助。

JavaScript迭代器知識點總結

【相關推薦:javascript影片教學web前端

##迭代就是指可以從一個

資料集中依照一定的順序,不斷取出資料的過程。

那麼迭代和遍歷有啥子差別呢?

    迭代強調依序取資料的過程,不保證把所有的資料都取完
  • #遍歷強調的是要把所有的資料依序全部取出
在JavaScript中,迭代器是能呼叫

next方法實作迭代的一個對象,該方法傳回一個具有兩個屬性的物件。

  • value:可迭代物件的下一個值
  • done:表示是否已經取出所有的資料了。 false表示還有數據, true表示後面已經沒有數據了。
迭代器簡單使用

透過可迭代物件中的迭代器工廠函數

Symbol.iterator來產生迭代器。

const arr = []console.log(arr)
登入後複製

JavaScript迭代器知識點總結

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())
登入後複製

JavaScript迭代器知識點總結

可以發現,迭代器

是取完最後一個值之後,也就是迭代器下一個值 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())
登入後複製

JavaScript迭代器知識點總結

不同迭代器之間互不干擾

可以多次呼叫迭代器工廠函數來產生多個迭代器,每個迭代器都表示對可迭代物件的一次性有序遍歷。

不同迭代器之間互不干擾,只會獨立地遍歷可迭代物件

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())
登入後複製

JavaScript迭代器知識點總結

迭代器物件可作為可迭代物件

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())
登入後複製

JavaScript迭代器知識點總結

完成但不完成

當我們迭代到

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())
登入後複製

JavaScript迭代器知識點總結

自訂迭代器

從上面的範例中,我們就可以知道是透過

透過迭代器工廠函數 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())
登入後複製

JavaScript迭代器知識點總結

乍一看,沒啥問題,但是如果我們使用

for-of來遍歷就能發現問題。

const counter = new Counter(3)for (let i of counter) {
  console.log(i)}console.log('另一轮迭代:')for (let i of counter) {
  console.log(i)}
登入後複製

JavaScript迭代器知識點總結#

使用 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)}
登入後複製

JavaScript迭代器知識點總結

提前终止迭代器

就和使用 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)}
登入後複製

JavaScript迭代器知識點總結

如果迭代器没有关闭,就可以继续从上次离开的地方继续迭代。数组地迭代器就是不能关闭的。

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迭代器知識點總結

【相关推荐:javascript视频教程web前端

以上是JavaScript迭代器知識點總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:csdn.net
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板