前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6之Iterator

ES6之Iterator

作者头像
19组清风
发布2021-11-15 15:25:11
2070
发布2021-11-15 15:25:11
举报
文章被收录于专栏:Web Front EndWeb Front End

Iterator

MDN:处理集合中的每个项是很常见的操作。JavaScript 提供了许多迭代集合的方法,从简单的for循环到map()和filter()。迭代器和生成器将迭代的概念直接带入核心语言,并提供了一种机制来自定义for...of循环的行为。

总结一下:

  • 接口机制,为各种不同的数据结构提供统一的访问机制。
  • 主要提供for of 循环
  • 其实Iterator迭代器对象本质就是可以使不可以迭代的对象变成可迭代对象。

迭代器对象是一个特殊的接口,所有迭代器对象都有一个next()方法,每次调用都返回一个结果对象。结果对象有两个属性:一个是value表示下一次返回的值,另一个是Boolean类型的值done,当没有更多可返回的数据时返回true。迭代器对象内部本质其实就是存在一个指针,用来指向集合中值的位置。

其实迭代器可以看作就是一个对象,这个对象存在一个next方法。next方法有两个属性一个是value一个是done。

  1. 迭代器协议

{ value:any, done: Boolean } 或者使用 Generator生成器直接生成满足迭代器协议对象(yield)

属性

必选

next

返回一个对象的无参函数,被返回对象拥有两个属性:done 和 value

Y

这是两个概念:可迭代协议、迭代器协议。通俗的讲,迭代器协议要求符合以下条件:

  • 首先,它是一个对象
  • 其次,这个对象包含一个无参函数 next
  • 最后,next 返回一个对象,对象包含 done 和 value 属性。其中 done 表示遍历是否结束,value 返回当前遍历的值。
  1. 可迭代协议

Symbol. Iterator

可迭代协议允许 JavaScript 对象去定义或定制它们的迭代行为, 例如(定义)在一个 for..of 结构中什么值可以被循环(得到)。一些内置类型都是内置的可迭代类型并且有默认的迭代行为, 比如 Array or Map, 另一些类型则不是 (比如Object) 。

为了变成可迭代对象, 一个对象必须实现 @@iterator 方法, 意思是这个对象(或者它原型链 prototype chain 上的某个对象)必须有一个名字是 Symbol.iterator 的属性:

属性

必选

[Symbol.iterator]

返回一个对象的无参函数,被返回对象符合迭代器协议

Y

如果让一个对象是可遍历的,就要遵守可迭代协议,该协议要求对象要部署一个以 Symbol.iterator 为 key 的键值对,而 value 就是一个无参函数,这个函数返回的对象要遵守迭代器协议。

自定义可迭代
  1. 满足可迭代协议。

存在[Symbol.iterator]属性。

  1. 满足迭代器协议。

[Symbol.iterator]属性要求返回一个可迭代的对象。

可迭代的对象可以使用我们源生实现,也可以使用Generator生成器函数实现。(详情参照Demo)

  • 自行实现需要[Symbol.iterator]方法返回一个对象,其实迭代器可以看作就是一个对象,这个对象存在一个next方法。next方法有两个属性一个是value一个是done。(函数内部闭包)
  • 使用Generator实现[Symbol.iterator],天然配合Generator和yield关键字进行生成可迭代对象。(他实质帮我们生成的自行实现需要的可迭代对象:拥有next方法,next方法每次返回value和done根据yield关键字作为指针)。
代码语言:javascript
复制
let authors = {
    allAuthors: {
        fiction: [
            'Agatha Christie',
            'J. K. Rowling',
            'Dr. Seuss'
        ],
        scienceFiction: [
            'Neal Stephenson',
            'Arthur Clarke',
            'Isaac Asimov',
            'Robert Heinlein'
        ],
        fantasy: [
            'J. R. R. Tolkien',
            'J. K. Rowling',
            'Terry Pratchett'
        ]
    }
}
// 自己实现迭代器协议
authors[Symbol.iterator] = function () {
    let allAuthors = this.allAuthors
    let keys = Reflect.ownKeys(allAuthors)
    let values = []
    return {
        next() {
            if (!values.length) {
                if (keys.length) {
                    values = allAuthors[keys[0]]
                    keys.shift()
                }
            }
            return {
                done: !values.length,
                value: values.shift()
            }
        }
    }
}

// 使用Generator生成器生成
authors[Symbol.iterator] = function* () {
    let allAuthors = this.allAuthors
    let keys = Reflect.ownKeys(allAuthors)
    let values = []
    while (1) {
        if (!values.length) {
            if (keys.length) {
                values = allAuthors[keys[0]]
                keys.shift()
                yield values.shift()
            } else {
                return false
            }
        } else {
            yield values.shift()
        }
    }
}
复制代码
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020年09月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Iterator
    • 自定义可迭代
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档