最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 彻底搞清楚 Iterator(遍历器)接口

    正文概述 掘金(毛小星)   2021-01-04   434

    彻底搞清楚 Iterator(遍历器)接口


    1. 什么是Iterator(遍历器)

    我们都知道 JavaScript 中对数组有很多种遍历方式,但是如果我们想像数组那样去遍历其他数据,我们该怎么办呢?Iterator遍历器就为我们提供了这种机制。 Iterator 是一个接口,它为 JavaScript 中的各种数据结构提供了一种规范。任何数据结构只要部署了 Iterator 接口,那么我们就可以使用 for...of 遍历这个数据结构 在 JavaScript 中部署了 Iterator 接口的有Array、String、Map、Set。 Iterator 的遍历过程是这样的。 (1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。 (2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。 (3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。 (4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。 我们可以通过 Symbol.iterator 属性获取到遍历器

    const arr = [1, 2, 3]
    const arrIterator = arr[Symbol.iterator]()
    console.log(arrIterator.next()) // { value: 1, done: false }
    console.log(arrIterator.next()) // { value: 2, done: false }
    console.log(arrIterator.next()) // { value: 3, done: false }
    console.log(arrIterator.next()) // { value: undefined, done: true }
    

    我们通过 Symbol.iterator 能获取到 iterator 遍历器,然后通过 next 方法获取到每一个属性的信息对象,信息对象中的 value 就是每一次遍历的值,done 代表了当前数据结构是否被遍历完,没有遍历完就为false,遍历完就为true。

    2. 实现 iterator 遍历器

    之前我们遍历自定义的数据结构可能是这样的

    const tools = {
        learn: ['html', 'css', 'js'],
        life: ['吃饭', '睡觉', '陪女朋友逛街'],
        hobby: ['看书', '篮球', '台球'],
    
        each(cb) {
            const all = [].concat(this.learn, this.life, this.hobby)
            for(item of all) {
                cb(item)
            }
        }
    }
    
    tools.each((item) => {
        console.log(item)
    })
    

    下面我们再来看看用"遍历器模式"实现

    const tools = {
        learn: ['html', 'css', 'js'],
        life: ['吃饭', '睡觉', '陪女朋友逛街'],
        hobby: ['看书', '篮球', '台球'],
    
        [Symbol.iterator]() {
            const all = [...this.learn, ...this.life, ...this.hobby]
            let index = 0
            return {
                next() {
                    return {
                        value: all[index],
                        done: index++ >= all.length,
                    }
                }
            }
        }
    }
    
    for(const item of tools) {
        console.log(item)
    }
    

    其实这样实现"迭代器模式",会稍显复杂一下,我们可以使用 ES6 中的 Generator 函数来实现迭代器

    const tools = {
        learn: ['html', 'css', 'js'],
        life: ['吃饭', '睡觉', '陪女朋友逛街'],
        hobby: ['看书', '篮球', '台球'],
    
        *[Symbol.iterator]() {
            const all = [...this.learn, ...this.life, ...this.hobby]
            for(item of all) {
                yield item
            }
        }
    }
    
    for (item of tools) {
        console.log(item)
    }
    
    1. 调用 Iterator 接口的场合
    • (1)结构赋值

    对数组和 Set 结构进行结构赋值时

    const set = new Set().add(1).add(2).add(3)
    const [first, second] = set
    console.log(first, second) // 1 2
    
    const arr = [1,2,3]
    const [first, ...rest] = arr
    console.log(first, rest) // 1 [2, 3]
    
    • (2)扩展运算符
    const str = 'king'
    console.log([...str]) // ['k', 'i', 'n', 'g']
    

    只要是某个数据机构部署了 Iterator 接口,那么它就可以使用 rest 运算符将其转化为数组

    • (3)Generator函数

    yield* 后面如果是一个可以遍历的数据结构,那么就会调用 Iterator 接口

    const g = function*() {
        yield 1
        yield* [2,3]
    }
    
    const i = g()
    console.log(i.next())
    console.log(i.next())
    console.log(i.next())
    console.log(i.next())
    
    • (4)其他场合
      • for...of
      • Array.from()
      • Map(), Set(), WeakMap(), WeakSet()(比如new Map([['a',1],['b',2]]))
      • Promise.all()
      • Promise.race()

    for...of循环

    了解 ES6 的同学一般去遍历数组会使用 Array.forEach() 方法

    const arr = [1,2,3]
    arr.forEach((item) => {
        console.log(item) // 1 2 3
    })
    

    但是 forEach 方法中无法使用 break 关键字,这就让我们处理某些逻辑的时候不那么方便 而 for...of 中却可以使用 break

    for (let item of arr) {
        console.log(item) // 1 2
        if (item > 1) break
    }
    

    起源地下载网 » 彻底搞清楚 Iterator(遍历器)接口

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元