我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript中Iterator迭代器接口和循环

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript中Iterator迭代器接口和循环

JavaScript的迭代器(Iterator)介绍

迭代器是数据结构遍历的一种机制(或者是什么我也不太懂的行业术语),为数据结构定义了统一的遍历规则。 迭代器(Iterator)主要是提供for...of使用,或者说,数据结构只有实现了迭代器(Iterator)接口才能使用for...of进行遍历数据,当一种数据结构没有实现迭代器(Iterator)接口时,去使用for...of操作,就会被抛出异常Uncaught TypeError: xxx is not iterable

JavaScript的迭代器(Iterator)的接口规范和操作过程:

  • 迭代器被调用时,返回一个指针对象,指针对象中必须包含一个next()的方法,每次调用next()方法,都会返回一个代表当前成员的信息对象,具有valuedone两个属性。value可为任意数据类型,done则是一个布尔类型,当调用next的方法时返回的对象中的done属性为false时,表示还可以继续进行遍历,当done属性为true时,表示遍历结束(没有的东西遍历了)了。
  • 迭代器(Iterator)对象的可选属性return()方法和throw()方法,也就是说当我们要自己去实现迭代器(Iterator)的时候,迭代器里必须要有next()方法,而return()方法和throw()是否要实现是可选的。而自己实现迭代器(Iterator)时,不管是next()return()还是throw()方法必须有返回值并且是对象,否则进行遍历的时候会抛出异常Uncaught TypeError: Iterator result xxx is not an object
  • 自己实现迭代器,只要给数据结构或者对象添加[Symbol.iterator]属性即可,其值必须是一个函数,返回一个只针对象,需遵循第2点的规范。为什么必须是[Symbol.iterator]的属性名,因为JavaScript的定义中,寻找遍历器时就是用这个字段,这也是一个标准规范。

下面是自己实现迭代器的演示代码:

const obj = {a: "age 18", b: 2};
// 实现迭代器
obj[Symbol.iterator] = function () {
    const keys = Object.keys(obj);
    let keyIndex = 0;

    return {
        next() {
            if (keys.length === 0 || keyIndex >= keys.length) {
                return {
                    value: undefined,
                    done: true
                }
            }

            const key = keys[keyIndex],
                value = [key, obj[key]];
            keyIndex += 1;

            return {
                value,
                done: false
            }
        }
    };
}

// 使用for...of进行遍历
for (let [key, value] of obj) {
    console.log(`${key}--${value}`)
}
// a--age 18
// b--2

返回参数简写,当返回正常值的时候,done字段可以省略,当循环结束的时候,value可以省略。但是注意不能两个都不写,不然会死循环,而且必须要有条件结束的操作,不然也会死循环,就像递归一样,一定要有条件结束的操作

Number.prototype[Symbol.iterator] = function () {
    let that = +this,
        i = that < 0 ? that : 0;
    that = that < 0 ? 0 : that;

    return {
        next() {
            if (i <= that) {
                const value = i;
                i += 1;
                return { value };
            }
            
            return { done: true };
        }
    };
};

for (const item of 20) {
    console.log(item);
}
// 数组的扩展运算符也是调用迭代器的哦
console.log([...5]);// [0, 1, 2, 3, 4, 5]

迭代器的可选参数return()throw()

return()方法是在遍历中断的时候会调用,如使用了break关键字中断或者抛出了异常都会调用这个方法。return()方法必须有返回参数并且要求是object类型的数据,否则就会抛出异常Uncaught TypeError: Iterator result undefined is not an object,至于object里内容要求是什么,我测了一下,毫无影响,返回空对象也没问题。

const obj = {
    size: 5,
    [Symbol.iterator]() {
        return {
            // 这里用箭头函数为的是可以直接使用this
            next: () => {
                if (this.size >= 0) {
                    const value = this.size;
                    this.size -= 1;
                    return {
                        value
                    };
                }

                return {
                    done: true
                };
            },
            return() {
                console.log("中断了");
                return { done: true };
                // 返回以下内容照样不会有问题,但是最好不这么操作,因为代码具有语义化才能更好的阅读
                // return {};
                // return new Date();
            }
        };
    }
};

for (const item of obj) {
    if (item < 3) {
        break;// 中断了
    }
    console.log(item);
}

throw()方法在迭代器中基本用不到,而是配合Generator使用,这里就不做过多的叙述。

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

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

for...of循环与for...in循环

上面已经详细的说明了迭代器(Iterator)主要是提供for...of循环使用,所以for...of循环时调用的是迭代器(Iterator),而循环的值是由实现的迭代器(Iterator)而定,而for...in循环是循环键值。

const arr = ["a", "b", "c"];
// 原生的数组迭代器(Iterator)的实现遍历时返回的是每一个元素
for (const item of arr) {
    console.log(item);
    // a
    // b
    // c
}
// for...in 返回的是key,这里是数组,key就是索引
for (const key in arr) {
    console.log(key);
    // 0
    // 1
    // 2
}

还有一个更直观的区别。for...of只是根据迭代器(Iterator)实现的内容返回结果,所以就不会遍历不在范围的东西,而for...in会把所有的键遍历出来。

const arr = ["a", "b", "c"];
arr.testValue = 1;

for (const item of arr) {
    console.log(item);
    // a
    // b
    // c
}
for (const item in arr) {
    console.log(item);
    // 0
    // 1
    // 2
    // testValue
}

到此这篇关于JavaScript中Iterator迭代器接口与循环的文章就介绍到这了,更多相关JavaScript Iterator 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript中Iterator迭代器接口和循环

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java中迭代器和for循环的优劣势有哪些

这篇文章给大家分享的是有关java中迭代器和for循环的优劣势有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于Java的实
2023-06-14

Java中的for-each循环与迭代器遍历有何区别?(Java中的for-each循环与迭代器遍历方式之间有哪些不同?)

Java中的for-each循环和迭代器遍历是遍历集合的两种方式。for-each循环简洁易用,但缺乏灵活性且不能并发遍历。迭代器遍历提供了更多的控制和灵活性,但性能可能较低,需要更多的代码。选择哪种方法取决于具体需求:需要快速、简洁的遍历且不需要修改/删除元素:for-each循环需要修改/删除元素、反向遍历或并发遍历:迭代器遍历
Java中的for-each循环与迭代器遍历有何区别?(Java中的for-each循环与迭代器遍历方式之间有哪些不同?)
2024-04-02

循环与迭代:Python 中高效数据处理的秘密武器

在 Python 中高效处理数据至关重要,循环和迭代提供了强大的工具来执行重复任务并遍历数据结构。本文将深入探讨这两种方法,并通过示例代码展示它们的应用。
循环与迭代:Python 中高效数据处理的秘密武器
2024-02-17

C++中单向链表类模板和iterator迭代器类的示例分析

这篇文章主要介绍了C++中单向链表类模板和iterator迭代器类的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。链表用来构建许多其它数据结构,如堆栈,队列和他们的派
2023-06-29

如何确定 PHP foreach 循环中的第一次和最后一次迭代

PHP foreach() 循环用于遍历数组中的每个元素。在本文中,我们将来学习如何使用 foreach() 循环以及如何获取数组的第一项和最后一项元素。PHP foreach() 语法foreach() 循环主要用于遍历数组的每个值。fo
如何确定 PHP foreach 循环中的第一次和最后一次迭代
2024-02-27

编程热搜

目录