ES6 Iterator的作用

103 阅读3分钟

ES6 Iterator的作用

ES6 引入了 Iterator(迭代器) 的概念,它是一种统一的接口机制,用于遍历数据结构中的元素。Iterator 的主要作用是为不同的数据结构(如数组、对象、Map、Set 等)提供一种统一的遍历方式,同时支持自定义遍历逻辑。

以下是 Iterator 的主要作用和应用场景:

  1. 统一遍历接口

Iterator 提供了一种统一的遍历接口,使得不同的数据结构可以通过相同的方式遍历。例如,数组、字符串、Map、Set 等都可以通过 for...of 循环遍历。

示例:

const array = [1, 2, 3];
const set = new Set([4, 5, 6]);

for (let value of array) {
    console.log(value); // 1, 2, 3
}

for (let value of set) {
    console.log(value); // 4, 5, 6
}
  1. 自定义遍历逻辑

通过实现 Iterator 接口,可以为自定义数据结构定义遍历逻辑。

示例:自定义迭代器

const myIterable = {
    data: [10, 20, 30],
    [Symbol.iterator]() {
        let index = 0;
        return {
            next: () => {
                if (index < this.data.length) {
                    return { value: this.data[index++], done: false };
                } else {
                    return { value: undefined, done: true };
                }
            }
        };
    }
};

for (let value of myIterable) {
    console.log(value); // 10, 20, 30
}
  1. Iterator 协议

Iterator 协议规定,一个对象要成为迭代器,必须实现一个 next() 方法。next() 方法返回一个包含以下两个属性的对象:

  • value:当前遍历的值。
  • done:布尔值,表示遍历是否结束。

示例:手动调用迭代器

const array = [1, 2, 3];
const iterator = array[Symbol.iterator]();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
  1. 可迭代对象

一个对象如果实现了 [Symbol.iterator] 方法,并且该方法返回一个迭代器,那么这个对象就是可迭代对象。ES6 中的许多内置数据结构(如数组、字符串、Map、Set 等)都是可迭代对象。

示例:检查对象是否可迭代

const array = [1, 2, 3];
const obj = { a: 1, b: 2 };

console.log(typeof array[Symbol.iterator]); // function
console.log(typeof obj[Symbol.iterator]); // undefined
  1. for...of 结合

for...of 循环是 ES6 引入的一种遍历可迭代对象的语法,它内部会自动调用对象的 [Symbol.iterator] 方法。

示例:

const map = new Map([
    ['a', 1],
    ['b', 2],
    ['c', 3]
]);

for (let [key, value] of map) {
    console.log(key, value); // a 1, b 2, c 3
}
  1. 内置迭代器

ES6 中的许多内置数据结构都实现了 Iterator 接口,例如:

  • 数组:遍历元素。
  • 字符串:遍历字符。
  • Map:遍历键值对。
  • Set:遍历元素。
  • NodeList:遍历 DOM 节点。

示例:遍历字符串

const str = 'hello';

for (let char of str) {
    console.log(char); // h, e, l, l, o
}
  1. 生成器函数

ES6 引入了生成器函数(function*),它可以方便地创建迭代器。生成器函数通过 yield 关键字返回值,并在每次调用 next() 时暂停执行。

示例:生成器函数

function* myGenerator() {
    yield 1;
    yield 2;
    yield 3;
}

const iterator = myGenerator();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
  1. 应用场景
  • 遍历数据结构:为数组、Map、Set 等提供统一的遍历方式。
  • 自定义数据结构:为自定义数据结构实现遍历逻辑。
  • 惰性求值:通过生成器函数实现按需生成值。
  • 异步迭代:结合 for await...of 实现异步遍历。

示例:惰性求值

function* fibonacci() {
    let [prev, curr] = [0, 1];
    while (true) {
        yield curr;
        [prev, curr] = [curr, prev + curr];
    }
}

const fib = fibonacci();
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
console.log(fib.next().value); // 3
  1. 异步迭代器

ES2018 引入了异步迭代器(Async Iterator),用于遍历异步数据源。异步迭代器通过 Symbol.asyncIterator 实现,并与 for await...of 结合使用。

示例:异步迭代器

async function* asyncGenerator() {
    yield await Promise.resolve(1);
    yield await Promise.resolve(2);
    yield await Promise.resolve(3);
}

(async () => {
    for await (let value of asyncGenerator()) {
        console.log(value); // 1, 2, 3
    }
})();

总结

Iterator 是 ES6 引入的一种统一的遍历接口,它为不同的数据结构提供了标准的遍历方式,同时支持自定义遍历逻辑。通过 Iterator,可以实现更灵活的数据遍历和处理,例如惰性求值、异步遍历等。结合 for...of 和生成器函数,Iterator 使得遍历操作更加简洁和强大。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github