Skip to content

迭代器模式

ES6 引入的迭代器模式,Iterable 接口定义了对象是否可迭代,Iterator 接口定义了对象如何迭代。

可迭代协议

任何实现了 [Symbol.iterator]() 方法的对象都被认为是可迭代的,这个方法必须返回一个 Iterator 对象。

ES 内置的可迭代对象有:数组、Map、Set、字符串、arguments 对象、NodeList 对象。

ts
// 没有实现迭代器工厂函数
const obj: any = {};
console.log(obj[Symbol.iterator]); // undefined
const num: any = 123;
console.log(num[Symbol.iterator]); // undefined

// 实现了迭代器工厂函数
const arr = [1, 2, 3];
console.log(arr[Symbol.iterator]); // [Function: values]
console.log(arr[Symbol.iterator]()); // Object [Array Iterator] {}
console.log(arr[Symbol.iterator]().next()); // { value: 1, done: false }

可迭代对象可以使用 for...of 循环,... 扩展运算符,解构赋值进行迭代。

ts
const str = "hello";

// for...of
for (const char of str) {
  console.log(char);
}

// 扩展运算符
console.log(...str); // h e l l o

// 解构赋值
const [first, second, ...rest] = str;
console.log(first, second, rest); // h e [ 'l', 'l', 'o' ]

迭代器协议

Iterator 接口定义了一个 next() 方法,该方法返回一个包含 donevalue 属性的对象,done 是一个布尔值,指示是否还有更多值可以迭代,value 包含当前的值。

done = true 时,value = undefined时,表示迭代结束。

ts
const map = new Map();
map.set("name", "John");
map.set("age", 30);

const mapIterator = map[Symbol.iterator]();
console.log(mapIterator.next()); // { value: [ 'name', 'John' ], done: false }
console.log(mapIterator.next()); // { value: [ 'age', 30 ], done: false }
console.log(mapIterator.next()); // { value: undefined, done: true }
console.log(mapIterator.next()); // { value: undefined, done: true }