• ES6 Iterator迭代器 与 Generator生成器 如何用js封装一个遍历所有可迭代数据结构的方法


    ES6 Iterator迭代器 与 Generator生成器

    1.1 为什么要有 Iterator

    在ES6语法中,有序数据结构已有许多
    如Array、Set、Map、String、类数组(如arguments)等
    当我们不确定数据是何种类型但又要对它进行遍历时,我们只能去做针对性的判断处理
    因此,一个统一的接口来遍历所有数据类型是很有必要的,而Iterator扮演了这一角色

    1.2 什么是Iterator

    1. 具有[Symbol.iterator]属性,且属性值是function类型
    2. 执行此function返回一个迭代器对象,此对象有next方法可顺序迭代子元素
    3. forof可遍历此迭代器

    在js中,实现了Iterator接口的数据结构都是可迭代的
    具体表现为数据结构的[Symbol.iterator]属性值是function类型

    const isIterable = target => typeof target?.[Symbol.iterator] === 'function'
    

    当迭代器顺序执行完毕之后,后续执行返回的done为true,作为迭代结束的标志

    function arrLike(){
        const it = arguments[Symbol.iterator]()
        console.log(it) // Object [Array Iterator] {}
        console.log(it.next()) // { value: 1, done: false }
        console.log(it.next()) // { value: 2, done: false }
        console.log(it.next()) // { value: 3, done: false }
        console.log(it.next()) // { value: undefined, done: true }
    }
    
    arrLike(1,2,3)
    

    封装一个迭代函数,用于遍历js中所有可迭代的数据结构

    // 判断是否可迭代
    const isIterable = target => typeof target?.[Symbol.iterator] === 'function'
    
    function each(target,callback){
        if(!isIterable(target)){
            throw 'the first parameter must be iterable(need a [Symbol.iterator] property)'
        }
        typeof callback !== 'function' && (callback = console.log)
    
        const iterator = target[Symbol.iterator]()
    
        // 或者用forof
        // for (const item of iterator) {
        //     callback(item)
        // }
        let item = {done:false}
        while(!item.done){
            item = iterator.next()
            !item.done && callback(item.value)
        }
    }
    
    each([2,3,4],console.log)
    each('abc',console.log)
    

    2 Generator生成器与迭代器

    一个生成器函数必定返回一个生成器对象,并且这个对象符合迭代器协议
    因此这个生成器对象可以被forof遍历,同样的具有next方法

    function* testGen(){} 
    console.log(testGen()) // Object [Generator] {}
    
    function* helloWorldGenerator(){
        yield 'hello'
        yield 'world'
        yield 'generator'
        return 'end'
    }
    
    const genIterator = helloWorldGenerator()
    console.log(genIterator.next()) // { value: 'hello', done: false }
    
    each(genIterator,console.log) 
    
  • 相关阅读:
    细细审视的你代码:异步消息处理
    [C++] 加速make的编译
    分析一下12306网站
    [Linux] 通过shell给unix socket发送数据
    shell中如何设置自增的变量
    多系统的 启动 顺序 修改
    对apk包进行odex优化的目的
    Android之所以不需要关闭后台运行程序 的 理由
    shell中如何设置自增的变量
    eclipse 小结
  • 原文地址:https://www.cnblogs.com/ltfxy/p/16131532.html
Copyright © 2020-2023  润新知