简单理解迭代器模式

简介: 这几天研究了一下迭代器模式,期间有一段时间经常搞不太懂一些概念与概念之间的关系,今天来整理一下。

这几天研究了一下迭代器模式,期间有一段时间经常搞不太懂一些概念与概念之间的关系,今天来整理一下。

迭代的一些基本概念

  1. 循环是迭代机制的基础
  2. 迭代在一个有序集合上进行
  3. 按照顺序反复多次执行一段程序,通常会有明确的终止条件

我的理解:

实际上就是为了优化循环,各种数据结构的循环。而且各种数据结构循环起来可以千奇百怪,为了合理的统一,就有了迭代器模式。

关键词

  • 可迭代对象
  • 可迭代协议(Iterable接口)
  • 迭代器
  • 迭代器协议(Iterator接口)
  • 迭代器对象( IteratorResult

关系图

网络异常,图片无法展示
|

QA式学习

Q:什么是可迭代对象?

A:满足可迭代协议(实现Iterable接口)的对象。

Q:可迭代协议是啥?

A:就是Iterable接口。满足可迭代协议的对象应该满足以下条件:

  1. 能够创建实现了Iterator接口的对象(实际上就是迭代器)
  2. 且可以通过迭代器Iterator消费。

举个例子,数组,集合,映射等等都满足可迭代协议。他们都可以用for...of遍历。

Q:什么是消费?

A:可以理解为遍历。有一个相关的概念“耗尽”,可以理解为遍历结束了。

Q:怎么满足可迭代协议?

A:你的对象需要有一个键名为Symbol.iterator的属性,指向一个迭代器工厂函数。啥意思嘞?就是说

//jojo是一个可迭代对象(数组)
console.log(jojo[Symbol.iterator]); // ƒ values() { [native code] }

JavaScript

Copy

作为一个工厂函数,我们调用它的话就应该可以生成一个迭代器

console.log(jojo[Symbol.iterator]()); //Array Iterator {}

JavaScript

Copy

Q:什么是迭代器?

A:首先,迭代器是用于迭代与其关联的对象的一次性使用对象,迭代器满足迭代器协议(实现Iterator接口)。一次性是指其在完成一次遍历(消费)之后就会被“耗尽”,这个时候再想遍历只能通过重新生成一个迭代器。

Q:迭代器协议说了啥?

A:迭代器协议说,只要你实现了Iterator接口,你就是个迭代器辣!你至少需要有一个next()方法来返回一个迭代器对象IteratorResult。这个对象包含两个属性:donevalue。其中done为一个布尔值,当done不为真时表示还可以通过调用next()取得下一个值,当done为真时,就可以被称为“耗尽”了。当done不为真时,value对象表示可迭代对象的下一个值,而当done不为真时,value就自然为undefined了。

模拟for...of

在MDN上有这么一段话

The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables.

大意

for...of语句为可迭代对象创建循环迭代。这些可迭代对象包括内置的StringArray,和一些类数组对象(比如argumentsNodeList),TypedArrayMapSet和用户定义的可迭代对象。

也就是说实际上使用for...of来遍历正是迭代器模式的一个应用。通过模拟一个数组的for...of遍历来更好地理解一下迭代器。

当我们普普通通for..of的时候发生了甚么事呢?

let arr = [1,2,3,4,5];
for(let item of arr)
    console.log(item);

JavaScript

Copy

实际上上面的代码可以等价于下面的代码。

let arr = [1,2,3,4,5];
let it = arr[Symbol.iterator]();//it->迭代器,通过调用arr[Symbol.iterator]()来生成
let item = it.next();//item->迭代器对象,包含着done和value两个属性
while(!item.done) {//当迭代器没有耗尽时
    console.log(item.value);//可以通过item.value来访问当前迭代到的值
    item = it.next();//继续迭代
}

JavaScript

Copy

自定义迭代器

刚刚提到了,for...of同样可以用于遍历用户定义的可迭代对象。一般的可迭代对象是不可以用for...of来遍历的,但是我们可以通过改造我们的对象,使其满足可迭代协议来使用for...of

let colors = {
    blue : "蓝色",
    green : "绿色",
    yellow : "黄色"
};
for(let color of colors)
    console.log(color);

JavaScript

Copy

网络异常,图片无法展示
|
尖尖达咩

现在我们让color对象满足Iterable接口

colors[Symbol.iterator] = function() {
    let keys = Object.keys(colors);
    let index = 0;
    return {
        next : function() {
            if (index < keys.length) {
                return {
                    value : colors[keys[index++]],
                    done : false
                }
            }
            return { done : true }
        }
    }
}

JavaScript

Copy

然后再次for...of循环,可以发现没有报错,并且正常循环输出了。

网络异常,图片无法展示
|

目录
相关文章
|
存储 算法 搜索推荐
掌握区间合并:解决实际问题的算法策略和应用案例【python LeetCode题目56】
掌握区间合并:解决实际问题的算法策略和应用案例【python LeetCode题目56】
|
人工智能 算法 安全
AI技术的未来发展与挑战
【6月更文挑战第15天】本文将探讨AI技术的未来发展和可能面临的挑战。随着科技的进步,AI已经在许多领域发挥了重要作用,但同时也带来了一些挑战。我们将从技术、伦理和社会角度来探讨这些问题。
461 6
|
Java
java判断时间是否为节假日(或指定的日期),是的话返回true,否返回false
java判断时间是否为节假日(或指定的日期),是的话返回true,否返回false
309 0
|
JavaScript 前端开发
jQuery 第八章(jQuery操作dom元素)
jQuery 第八章(jQuery操作dom元素)
100 0
|
存储 Kubernetes 容器
kubernetes创建nfs存储类
kubernetes创建nfs存储类
370 0
|
存储 安全 编译器
C++之引用(下)
C++之引用(下)
197 0
|
算法 搜索推荐 C++
第九章(14):STL之常用拷贝和替换算法
第九章(14):STL之常用拷贝和替换算法
第九章(14):STL之常用拷贝和替换算法
|
Java API Android开发
Kotlin 协程 看这一篇就够了
Kotlin 协程 看这一篇就够了
2329 1
Kotlin 协程 看这一篇就够了
|
SQL Web App开发 关系型数据库
MySQL数据库操作,指导手册
MySQL数据库操作,如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL
800 0
MySQL数据库操作,指导手册
|
安全 数据库
在kali中部署DVWA靶场
在kali中部署DVWA靶场
928 0
在kali中部署DVWA靶场