es6 Iterator迭代器

Iterator迭代器

它的作用一共有三个:

  • 第一是为各种数据结构,提供一个统一的、简便的访问接口
  • 第二使得数据结构的成员能够按某种次序排列
  • 第三ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of循环

1.Iterator原理解释
2.给对象添加iterator
一、iterator原理解释
我们先简单写一个数组,然后通过for of 遍历

        let arr = ["aaa","bbb","ccc"];
        for(let i of arr){
            console.log(i)
        }
        console.log(arr)

在这里插入图片描述

我们点开这个数组的原型,就会发现其中包含了一个名为 Symbol.iterator的方法
在这里插入图片描述
我们尝试打印这个方法,会发现其中包含一个next()方法,在试着调用next(),这个时候我们就发现了,iterator其实是一个类似于单链表的数据结构,一层一层往下指,从而实现了遍历

        let arr = ["aaa","bbb","ccc"];
        for(let i of arr){
            console.log(i)
        }
        console.log(arr)
        let iter = arr[Symbol.iterator]()
        console.log(iter)
        console.log(iter.next())
        console.log(iter.next())
        console.log(iter.next())
        console.log(iter.next())

在这里插入图片描述
所以我们可以认为,像数组一样原型内置Symbol.iterator属性的,就认为是可以for of遍历的,没有这个属性的,我们添加上这个属性,那么它就可以实现for of遍历。
以下是原生默认具备iterator接口的数据结构

  • Array
  • Set
  • Map
  • String
  • arguments对象
  • NodeList对象
    拿字符串测试以下是否具有iterator接口
        let arr = "starry";
        for(let i of arr){
            console.log(i)
        }
        console.log(arr)
        let iter = arr[Symbol.iterator]()
        console.log(iter)
        console.log(iter.next())
        console.log(iter.next())
        console.log(iter.next())
        console.log(iter.next())

在这里插入图片描述
二、给对象添加iterator
先来一个没有意义的简单添加,因为对象是非线性的,所以不包含iterator迭代器,使用for of 就会报错

       let obj = {
        0:"aaa",
        1:"bbb",
        2:"ccc",
        // length:3,
        // [Symbol.iterator]: Array.prototype[Symbol.iterator]
       }
       for(let i of obj){
        console.log(i) //报错
       }

在这里插入图片描述
但是我们将注释的代码放出来,给对象一个长度属性和一个和数组一样的迭代器接口就可以成功for of了
在这里插入图片描述
遍历成功!但是这样的添加是没有太大意义的,有意义的情况是下面这种需要自己手写一个迭代器的对象。

        let obj = {
            code: 200,
            name: "starry",
            list: [1, 2, 3, 4]
        }
        for (let i of obj) { // 报错
            console.log(i) 
        }

上面的代码,直接for of 肯定会报错,假如我们想要遍历list的内容怎么办,也许你会说,直接obj.list就可以实现遍历,但是如果obj是别人私有的库呢,list是一个私有属性呢?所以转换身份,我们作为一个JS库开发者,写了一个对象,想让别人轻松使用for of 遍历自己对象的内容,就需要自己手动写一个iterator。

        let obj = {
            code: 200,
            name: "starry",
            list: ["A", "B", "c"],
            [Symbol.iterator](){
                let index = 0;
                return {
                    next:() => { // 使用箭头函数改变this指向
                        return {value:this.list[index++],done: index === (this.list.length+1) ? true : false}
                        // +1是因为迭代到C的时候index就已经是3了,不加1done为true就不会打印c了
                    }
                }
            }
        }
        for(let i of obj){
            console.log(i)
        }
        let iter = obj[Symbol.iterator]()
        console.log(iter.next())
        console.log(iter.next())
        console.log(iter.next())
        console.log(iter.next())

在这里插入图片描述
这里扩展一下,只要拥有了iterator接口,使用展开运算符就可以直接拿到把迭代器里的内容变成数组,比如这里的obj

        let obj = {
            code: 200,
            name: "starry",
            list: ["A", "B", "c"],
            [Symbol.iterator](){
                let index = 0;
                return {
                    next:() => {
                        return {value:this.list[index++],done: index === (this.list.length+1) ? true : false}
                    }
                }
            }
        }
        console.log(...obj) // A B c
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值