JS中迭代器

JS中迭代器,第1张

1.迭代器

概念:

        遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历 *** 作

在JS中,Iterator接口可以通俗的理解为对象的属性,属性的名字为symbol.Iterator()

特性:

        ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费;原生具备 iterator 接口的数据(可用 for of 遍历):

 Array;Arguments;Set;Map;String;TypedArray;NodeList

工作原理:

        1. 创建一个指针对象,指向当前数据结构的起始位置;
        2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
        3. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;
        4. 每调用 next 方法返回一个包含 value 和 done 属性的对象;
        注:需要自定义遍历数据的时候,要想到迭代器;

 // 声明一个数组,因为数组具备Iterator属性
    const xiyou = ["唐僧", "孙悟空", "猪八戒", "沙僧"];

    // 使用for...of遍历数组
    for (let v of xiyou) {
        console.log(v);
    }

  以上代码输出结果为下图片,因为我们数组具有Iterator接口,所以可以直接使用for...of进行遍历

         上述代码还可以采用for...in进行遍历。for...in遍历的结果是键名,即为1,2,3,4......,for...of遍历的结果为键值。

接下来正式解释iterator的工作原理:

        1. 创建一个指针对象,指向当前数据结构的起始位置;

let iterator = xiyou[Symbol.iterator]();

         2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;

         3. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;

         4. 每调用 next 方法返回一个包含 value 和 done 属性的对象;

        调用next方法,next不停的指向下一个成员,当我们的遍历结束之后done的值就变为true.同时value值也变为undefined。每次返回的结果都是一个对像。

// 调用对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

2.迭代器自定义遍历对象

        因为对象是不存在iterator这个属性的,所以如下代码遍历的时候会报banji这个对象不能被遍历的错。为了解决该问题,我们自定义遍历对象。

        PS:此处会有疑问,为什么我不直接使用for...in遍历呢?for...in遍历时可以的,但是本地方是像使用for...of进行遍历,同时返回的值是我们stus中的一个成员。又有人会有疑问,为什么不直接使用banji.syus.forEach()进行遍历呢?这个方法也是可行的,但是这不符合面向对象 的一种思想。

// 声明一个对象
    const banji = {
        name: "终极一班",
        stus: [
            "xiaoming",
            "xiaoning",
            "xiaotian",
            "knight"
        ]
    }

    // 遍历改对象
    for (let v of banji) {
        console.log(v);
    }

下面开始我们自定义遍历数据

[Symbol.iterator]() {

        }

        加入上述代码遍历之后会报如下错误:

         报没有对象的错,既然没有对象,那我们就返回一个对象。

[Symbol.iterator]() {
            return {};
        }

         但是加了对象之后依旧会报上述错误,报undefined不是一个函数的错误的原因是因为我们iterator属性中有一个next的方法,而我们代码中没有,为了解决此问题,我们创建一个next方法。

[Symbol.iterator]() {
            return {
                next: function () {

                }
            };
        }

添加上述代码后依旧会报错,报错为我们迭代器返回的结果是一个undefined,这个undefined不是一个对象。这是因为我们的next每次返回的结果都应该是包含value和done属性的一个对象。但是我们上述代码没有value和done属性。为了解决此问题我们添加这两个属性。

 next: function () {
                    return {
                        value: "aaa",
                        done: false
                    }
                }

添加上述代码不会报错,但是会一直运行,怕cpu承受不住,此处不截图了。之所以会出现一直输出,没有停止的现象是因为我们每次调用next都会返回done为false的状态,那就表示我们对象没有被遍历完,需要一直遍历。那么为了解决这个问题我们就要对返回的结果进行处理。

 return {
                next: () => {
                    if (index < this.stus.length) {
                        const result = { value: this.stus[index], done: false };
                        // 下标自增
                        index++;
                        // 返回结果
                        return result;
                    } else {
                        return { value: undefined, done: true }
                    }

                }
            };

添加以上代码可以完成我们想通过iterator对对象进行的一个遍历。 

完整的代码如下:

 // 声明一个对象
    const banji = {
        name: "终极一班",
        stus: [
            "xiaoming",
            "xiaoning",
            "xiaotian",
            "knight"
        ],
        [Symbol.iterator]() {
            // 先声明一个索引变量
            let index = 0;
            return {
                next: () => {
                    if (index < this.stus.length) {
                        const result = { value: this.stus[index], done: false };
                        // 下标自增
                        index++;
                        // 返回结果
                        return result;
                    } else {
                        return { value: undefined, done: true }
                    }

                }
            };
        }
    }



    // 遍历改对象
    for (let v of banji) {
        console.log(v);
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1296717.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存