Iterator迭代器

本文详细解释了JavaScript中的迭代器概念,包括其定义、next方法的要求,以及如何在数组和对象上实现迭代器。同时介绍了可迭代对象协议、for...of语法的应用以及迭代器中断的情况。
摘要由CSDN通过智能技术生成

Iterator迭代器

  • 迭代器是指用户在容器对象上遍访问的对象,使用该接口的时候无序关心对象的内部实现细节
  • 迭代器的定义中可以看出来,迭代器是帮助我们对某个数据结构进行遍历的对象
  • JavaScript中,迭代器是一个具体的对象
    • 产生一系列值,不论是有限还是无限个的标准方式
    • 在JavaScript中,这个标准就是一个特定next方法
  • next方法有如下的要求
    • 一个无参数或者是一个参数的函数,返回一个应当拥有以下两个属性的对象
    • done(boolean)
      • 如果迭代器可以产生许可列中的下一个值,则为false
      • 如果迭代器已经迭代完毕,则为true,这种情况下,value的值是可以选择的,如果它依然存在,则为迭代之后的默认返回值
    • value
      • 迭代器返回的任何JavaScript值,done为ture的时候可以省略
  1. 代码示例
    const infos = {
        name: ["koke", "james", "curry"]
    }
    let index = 0
    const infoIterator = {
        next: function () {
            if (index < infos.name.length ) {
                return {done:false, value: infos.name[index++]}
            }
            return {done:true, value: undefined}
        }
    }
    console.log(infoIterator.next())
    console.log(infoIterator.next())
    console.log(infoIterator.next())
    console.log(infoIterator.next()) 
    //{done: false, value: 'koke'}
    //{done: false, value: 'james'}
    //{done: false, value: 'curry'}
    //{done: true, value: undefined}
    
    const names = ["abc", "cba","bac"]
    const nums = [100, 24, 55, 66, 86]
    function createArrayIterator(arr) {
        let index = 0
        return {
            next: function () {
                if (index < arr.length) {
                    return {done:false, value: arr[index++]}
                }
                return {done: true}
            }
        }
    }
    const namesIterator = createArrayIterator(names)
    const numsIterator = createArrayIterator(nums)
    console.log(namesIterator.next())
    console.log(namesIterator.next())
    console.log(namesIterator.next())
    console.log(namesIterator.next())
    console.log(numsIterator.next())
    console.log(numsIterator.next())
    console.log(numsIterator.next())
    // {done: false, value: 'abc'}
    // {done: false, value: 'cba'}
    // {done: false, value: 'bac'}
    // {done: true}
    // {done: false, value: 100}
    // {done: false, value: 24}
    // {done: false, value: 55
    
  2. 可迭代对象
    迭代器对象和可迭代对象是一个不同的东西,虽然存在关联。
    • 可迭代对象协议
      • 实现了[Symbol.iterator]为key的方法,而且这个方法返回了一个迭代器对象
    const infos = {
        friends: ["kobe", "james","curry"],
        [Symbol.iterator]: function () {
            let index = 0
            const infosIterator = {
                next: () => {
                if (index < this.friends.length) {
                    return {done: false, value: this.friends[index++]}
                }
                return {done: true}
                }
            }
            return infosIterator
        }
    }
    console.log(infos[Symbol.iterator])
    console.log(infos[Symbol.iterator]().next())
    for(let item of infos.friends) {
        console.log(item)
    }
    //  kobe
    //  james
    //  curry
    // ƒ () {
    //         let index = 0
    //         const infosIterator = {
    //             next: function () {
    //             if (index < infos.friends.length) {
    //                 return {done: false, value: infos.frien…
    // {done: false, value: 'kobe'}
    
  3. 可迭代对象的应用
    • 只要在对象的属性上部署了Iterator接口,具体形式为给对象添加Symbol.iterator属性,这个属性指向一个迭代器方法,这个迭代器会返回一个特殊的对象,迭代器对象。
    • 部署这个属性并且实现了迭代器方法后的对象叫做可迭代对象
    1. JavaScript中的语法
      for…of 展开语法 yield* 解构赋值 ...默认调用iterator接口
    2. 创建一些对象
      new Map([Iterable]) new WeakMap([Iterable]) new Set([Iterable]) new WeakSet([Iterable])
    3. 一些方法的调用
      Promise.all([Iterable]) Promise.race(Iterable) Array.from(Iterable)
    4. 原生迭代器对象
      String Array Map Set arguments NodeList TypedArray
    5. 示例
    for (const item of info) {
        console.log(item)
    }
    console.log([...info, "curry"])
    const [name1, name2] = info
    
    const names = ["ab", "d","djk"]
    const info = {
        name: 'alsd',
        dhafkl:'jsdklf'
    }
    function foo(arg1, arg2, arg3) {
        console.log(arg1,arg2,arg3)
    }
    // foo(...info) // 对象没有迭代器方法,需要自己加
    foo(...names)
    
    const names = ["ab", "d","djk"]
    const info = {
        name: 'alsd',
        dhafkl:'jsdklf',
        [Symbol.iterator]: function () {
            // const keys = Object.keys(this)
            // const values = Object.values(this)
            const entries = Object.entries(this)
            let index = 0
            const iterator = {
                next: function (){
                    if (index < entries.length) {
                        return {done:false, value: entries[index++]}
                    }
                    return {done: true}
                }
            }
            return iterator
        }
    }
    function foo(arg1, arg2, arg3) {
        console.log(arg1,arg2,arg3)
    }
    foo(...info)
    // foo(...names)
    
    const info = { //数组没有迭代器方法
        name: 'alsd',
        dhafkl:'jsdklf',
        [Symbol.iterator]: function () {
            // const keys = Object.keys(this)
            // const values = Object.values(this)
            const entries = Object.entries(this)
            let index = 0
            const iterator = {
                next: function (){
                    if (index < entries.length) {
                        return {done:false, value: entries[index++]}
                    }
                    return {done: true}
                }
            }
            return iterator
        }
    }
    function foo(arg1, arg2, arg3) {
        console.log(arg1,arg2,arg3)
    }
    // foo(...info)
    // foo(...names)
    const set = new Set(["aa","bb","cc"])
    for (const string of set) {
        console.log(string)
    }
    const set1 = new Set("abc")
    for (const string of set1) {
        console.log(string)
    }
    const  set2 = new Set(info)
    console.log(set2)
    const setIterator = set[Symbol.iterator]()
    console.log(setIterator.next())
    console.log(setIterator.next())
    console.log(setIterator.next())
    console.log(setIterator.next())
    // aa
    // bb
    // cc
    // a
    // b
    // c
    // Set(2) {Array(2), Array(2)}
    // {value: 'aa', done: false}
    // {value: 'bb', done: false}
    // {value: 'cc', done: false}
    // {value: undefined, done: true}
    
    function foo() {
        for (const argument of arguments) {
            console.log(argument)
        }
    }
    foo(123, 321, 111 ,222 )
    
  4. 迭代器的中断
    迭代器在某些情况下会在没有完全迭代的情况下中断
    遍历的过程中通过break ruturn throw 中断了循环操作
    在结构的时候,没有解构所有的值
    class Person {
        constructor(name, age, height, friends) {
            this.name = name
            this.age = age
            this.height = height
            this.friends = friends
        }
        running() {
        }
        [Symbol.iterator]  () {
            let index = 0
            const iterator = {
                next: () => {
                    if(index< this.friends.length) {
                        return {done: false, value: this.friends[index++]}
                    }
            },
            return: () => {
                console.log("监听到迭代器中断了")
                return {done: true}
    
            },
            }
            return iterator
    
        }
    }
    const p1 = new Person("jkld",324,234,["jsdafkl","jkasdklfj"])
    
    // for (const person of p1.friends) {
    //     console.log(person);
    // }
    
    for (const person of p1) {
        console.log(person)
        if(person === "jsdafkl") {
            break
        }
    }
    // jsdafkl
    // 监听到迭代器中断了
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值