简单理解迭代器模式

876天前 · 代码 · 1086次阅读

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

迭代的一些基本概念

  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] }

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

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

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);

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

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();//继续迭代
}

自定义迭代器

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

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

尖尖达咩

现在我们让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 }
        }
    }
}

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

成功辽

以上就是我对迭代器的一些理解,如果有什么问题欢迎指正!

👍 16

js 迭代器

最后修改于875天前

评论

取消回复
贴吧 狗头 原神 小黄脸
收起

贴吧

  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡

狗头

  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头

原神

  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神

小黄脸

  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  1. qinians 866天前

    感谢 huaji_han

  2. Hêlli 867天前

    Hello

    1. 季悠然 866天前

      Guten Tag

  3. 869天前

    谢谢分享!

目录

avatar

季悠然

寻找有趣的灵魂

140

文章数

2073

评论数

3

分类

好热啊

arknights!

所有苦难与背负的尽头,都是行云流水般的此世光阴。

Priest

1484