Skip to content

Iterator(遍历器)

  1. 为各种数据结构,提供一个统一的、简便的访问接口;(统一)

  2. 是使得数据结构的成员能够按某种次序排列;(按序)

  3. 是 ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费。

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

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

计算生成的

  • entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值;对于 Set,键名与键值相同。Map 结构的 Iterator 接口,默认就是调用 entries 方法。
  • keys() 返回一个遍历器对象,用来遍历所有的键名。
  • values() 返回一个遍历器对象,用来遍历所有的键值

例子

  1. Array
js
Array.prototype._protoKey = function() {
	console.log('Array_protoKey');
};
let arr = [1, 2, 3, 4, 5];
// for
console.log('--------of-------------');
for (var item of arr) {
	console.log(`${item}`); // 1,2,3,4,5
}
  1. Map
js
let map = new Map();

map.set({ a: 1 }, 'content');
map.set({ a: 2 }, 'content2');
map.set(3, 'content2');
// for
for (var item of map) {
	console.log(`${item}`);
}
// 结果为:
// [object Object],content
// [object Object],content2
// 3,content2
  1. Set
js
let set = new Set();

set.add({ a: 1 });
set.add({ a: 1 });
set.add(3);
set.add(3);
set.add(4);
// for
for (var item of set) {
	console.log(`${item}`);
}
// 结果为:
// [object Object]
// [object Object]
// 3
// 4

默认调用 Iterator 接口的场合

  1. 解构赋值

在对数组和 Set 进行结构赋值的时候就是调用的Symbol.iterator

js
let set = new Set()
	.add('a')
	.add('b')
	.add('c');

let [x, y] = set;
// x='a'; y='b'

let [first, ...rest] = set;
// first='a'; rest=['b','c'];
  1. 扩展运算符

  2. yield*

yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。

js
let generator = function*() {
	yield 1;
	yield* [2, 3, 4];
	yield 5;
};

var iterator = generator();

iterator.next(); // { value: 1, done: false }
iterator.next(); // { value: 2, done: false }
iterator.next(); // { value: 3, done: false }
iterator.next(); // { value: 4, done: false }
iterator.next(); // { value: 5, done: false }
iterator.next(); // { value: undefined, done: true }
  1. 其他场合

由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口。下面是一些例子。

  • for...of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()(比如 new Map([['a',1],['b',2]]))
  • Promise.all()
  • Promise.race()

类数组

类数组(没有 Inteador,所有不能使用 for of)

js
let likeArr = {
	0: 'gz0',
	1: 'gz1',
	2: 'gz2',
	3: 'gz3',
	4: 'gz4',
	length: 5,
};

for (var item of likeArr) {
	//  likeArr is not iterable
	console.log(`${item}`);
}

我们可以改造

js
let iterable = {
	0: 'a',
	1: 'b',
	2: 'c',
	length: 3,
	[Symbol.iterator]: Array.prototype[Symbol.iterator], //这句话是重点
};
for (let item of iterable) {
	console.log(item); // 'a', 'b', 'c'
}

第二种方式

js
let iterable = {
	0: 'a',
	1: 'b',
	2: 'c',
	length: 3,
};

iterable = Array.from(iterable); //装换成数组
for (let item of iterable) {
	console.log(item); // 'a', 'b', 'c'
}