ES6的迭代器Iterator深入理解(写一个和ES6一样的自定义的迭代器)

什么是迭代器模式

迭代器(iterator)有时又称光标(cursor)是程序设计的软件设计模式,可在容器对象(container,例如链表或数组)上遍访的接口,设计人员无需关心容器对象的内存分配的实现细节。 —百度百科

一个比方:电视机的频道当成一个数据集合,遥控器就相当于一个迭代器

迭代器模式

分离了集合对象的遍历行为,抽象出一个迭代器来负责,我无需知道内部的数据结构,又可以让外部透明的进行访问

为什么js要产生迭代器

ES6之前
在这里插入图片描述
上面不同的数据结构都要使用不同的遍历方法,否则会报语法错位,这样不利于简化编程,所以产生了一种方式来统一遍历方式

ES6的迭代器

const items = ['first','second','third']
const it = items[Symbol.iterator]() //调用了ES6的迭代器方法 it成为了一个迭代器

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

调用迭代器之后会产生下面对象,有两个属性,其中done为true时表示不可以遍历了,数据遍历完了

在这里插入图片描述

自定义迭代器

用迭代器模式
写一个和上面一样的迭代器方法

class Iterator {
    constructor(list) {
        this.list = list
        this.index = 0;
    }
    // 相当于上面迭代器的next()方法
    next() {
        if (this.hasNext()) {
            return {
                value: this.list[this.index++],
                done: false
            }
        }else{
            return{
                value: undefined,
                done: true
            }
        }

    }

    hasNext() {
        if (this.list.length > this.index) {
            return true
        } else {
            return false
        }
    }
}

// 获取迭代器

class Factory {
    constructor(list) {
        this.list = list
    }
    // 获取迭代器 相当于上面ES6的 [Symbol.iterator]() 方法
    // 面向对象思想写法 写这个Factory的作用
    getIteractor() {
        return new Iterator(this.list)
    }
}




效果相同
let arr = [9, 8, 7]

let model = new Factory(arr)
let iterator = model.getIteractor()

console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());


getIteractor() 方法,获取迭代器 相当于上面ES6的 Symbol.iterator 方法,写这个Factory的作用,面向对象思想写法

在这里插入图片描述

Iterator的概念

遍历器(Iterator)它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作
(即依次处理该数据结构的所有成员, 之前只有数组和NodeList等比较特殊的类数组才拥有该特性)

Iterator的三个作用

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

Iterator的实现步骤

  1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象
  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员
  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置

每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

以我的理解:学过数据结构的人会将其类比为链式存储结构

Iterator的实现原理

由于 Iterator 只是把接口规格加到数据结构之上,所以,遍历器与它所遍历的那个数据结构,实际上是分开的,完全可以写出没有对应数据结构的遍历器对象,或者说用遍历器对象模拟出数据结构。

默认的迭代器(Iterator)接口

ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)

一种数据结构只要部署了 Iterator 接口,我们就称这种数据结构是“可遍历的”(iterable)。

Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for…of循环(。当使用for…of循环遍历某种数据结构时,该循环会自动去寻找 Iterator 接口。

原生具备 Iterator 接口的数据结构如下。

  1. Array
  2. Map
  3. String
  4. TypedArray(个底层二进制数据缓存区的类数组)
  5. Sett
  6. NodeList 对象

for… …of循环与迭代器的关系

数组原生具备iterator接口(即默认部署了Symbol.iterator属性),for…of循环本质上就是调用这个接口产生的遍历器,可以用下面的代码证明。

const week = ['Monday','Tuesday','Wednesday']
for(let v of week){
    console.log(v);
}

const obj = {}
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr)

for(let  v  of obj){
    console.log(v);
}

上侧代码中,空对象obj部署了数组arr的Symbol.iterator属性,结果obj的for…of循环,产生了与arr完全一样的结果。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ES6迭代器Iterator)是一种新的遍历机制,它有两个核心特点。首先,迭代器一个接口,通过Symbol.iterator方法来创建迭代器,并通过迭代器的next()方法来获取数据。其次,迭代器是用于遍历数据结构的指针,类似于数据库的游标。例如,我们可以使用迭代器来遍历数组。比如,对于数组\[20,30,50,20,50\],我们可以通过arr\[Symbol.iterator\]()来创建一个迭代器,然后使用迭代器的next()方法来逐个获取数组中的元素。\[1\] 除了数组,具备Iterator接口的数据结构都可以进行解构赋值和扩展运算符(...运算符)操作。例如,字符串也具备Iterator接口,我们可以使用扩展运算符将字符串转换为字符数组。比如,对于字符串'hello',我们可以使用\[...str\]来将其转换为字符数组\['h', 'e', 'l', 'l', 'o'\]。这是因为字符串是具备Iterator接口的数据结构,我们可以自定义迭代器来遍历字符串中的字符。\[2\] 除了数组和字符串,还有其他可迭代的数据结构,比如类型数组(TypedArray)。我们可以使用for...of循环来遍历这些可迭代的数据结构。例如,对于数组\["zero", "one", "two"\],我们可以使用for...of循环来逐个输出数组中的元素。\[3\] #### 引用[.reference_title] - *1* [ES6 迭代器Iterator](https://blog.csdn.net/weixin_49342009/article/details/122665011)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [es6 迭代器iterator](https://blog.csdn.net/weixin_43443341/article/details/121417247)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ES6迭代器 Iterator 详细介绍](https://blog.csdn.net/weixin_43856422/article/details/128290261)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值