JavaScript 迭代器和可迭代对象

JavaScript Iterables and Iterators

JavaScript 提供了一个迭代数据结构的协议。该协议定义了如何使用 for...of 循环迭代这些数据结构。

该协议的概念可以分为

  • iterable (可迭代对象)
  • iterator (迭代器)

iterable 协议指出,一个可迭代对象应具有 Symbol.iterator 键。

JavaScript Iterables (可迭代对象)

拥有 Symbol.iterator() 方法的数据结构称为可迭代对象。例如,Arrays(数组)、Strings(字符串)、Sets(集合)等。

JavaScript Iterators (迭代器)

迭代器是 Symbol.iterator() 方法返回的对象

迭代器协议通过 next() 方法一次访问可迭代对象(数据结构)的每个元素。


让我们来看一个可迭代对象拥有 Symbol.Iterator() 的示例

const arr = [1, 2 ,3];

// calling the Symbol.iterator() method
const arrIterator = arr[Symbol.iterator]();

// gives Array Iterator
console.log(arrIterator);

const str = 'hello';

// calling the Symbol.iterator() method
const strIterator = str[Symbol.iterator]();

// gives String Iterator
console.log(strIterator);

输出

Array Iterator {}
StringIterator {}

在这里,调用数组和字符串的 Symbol.iterator() 方法会返回它们各自的迭代器。


Iterate Through Iterables (迭代可迭代对象)

您可以使用 for...of 循环迭代这些可迭代对象。您可以这样迭代 Symbol.iterator() 方法

const number = [ 1, 2, 3];

for (let n of  number[Symbol.iterator]()) {
    console.log(n);
}

输出

1
2
3

或者您可以像这样直接迭代数组

const number = [ 1, 2, 3];

for (let n of  number) {
    console.log(n);
}

在这里,迭代器允许 for...of 循环迭代数组并返回每个值。


JavaScript next() Method (next() 方法)

迭代器对象有一个 next() 方法,该方法返回序列中的下一个项。

next() 方法包含两个属性:valuedone

  • value (值)
    value 属性可以是任何数据类型,表示序列中的当前值。
  • done (完成)
    done 属性是一个布尔值,指示迭代是否完成。如果迭代未完成,则 done 属性设置为 false,否则设置为 true

让我们来看一个数组可迭代对象的示例

const arr = ['h', 'e', 'l', 'l', 'o'];

let arrIterator = arr[Symbol.iterator]();

console.log(arrIterator.next()); // {value: "h", done: false}
console.log(arrIterator.next()); // {value: "e", done: false}
console.log(arrIterator.next()); // {value: "l", done: false}
console.log(arrIterator.next()); // {value: "l", done: false}
console.log(arrIterator.next()); // {value: "o", done: false}
console.log(arrIterator.next()); // {value: undefined, done: true}

您可以重复调用 next() 来迭代 arrIterator 对象。

  • next() 方法返回一个具有 valuedone 两个属性的对象。
  • next() 方法到达序列末尾时,done 属性将设置为 false

让我们看看 for...of 循环如何执行上述程序。例如,

const arr = ['h', 'e', 'l', 'l', 'o'];

for (let i of arr) {
    console.log(i);
}

输出

h
e
l
l
o

for...of 循环执行的操作与上面的程序完全相同。

for...of 循环不断地在迭代器上调用 next() 方法。一旦达到 done:truefor...of 循环就会终止。


User Defined Iterator (用户定义的迭代器)

您还可以创建自己的迭代器并调用 next() 来访问下一个元素。例如,

function displayElements(arr) {

    // to update the iteration
    let n = 0;

    return {

        // implementing the next() function
        next() {

            if(n < arr.length) {
                return {
                    value: arr[n++],
                    done: false
                }
            }

            return {
                value: undefined,
                done: true
            }
        }
    }
}

const arr = ['h', 'e', 'l', 'l', 'o'];

const arrIterator = displayElements(arr);

console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());

输出

{value: "h", done: false}
{value: "e", done: false}
{value: "l", done: false}
{value: "l", done: false}
{value: "o", done: false}
{value: undefined, done: true}

在上面的程序中,我们创建了自己的迭代器。displayElements() 函数返回 valuedone 属性。

  • 每次调用 next() 方法时,该函数都会执行一次并显示数组的值。
  • 最后,当数组的所有元素都耗尽时,done 属性将设置为 truevalueundefined

另请阅读

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战