4.1Iterator遍历器
4.1.1Iterator(遍历器)的概念
- 遍历器(Iterator)是一种接口,为了各种不同的数据结构提供统一的访问机制。
- 任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
- Iterator的作用有三个:
- 一是为各种数据结构,提供一个统一的、简便的访问接口;
- 二是使得数据结构的成员能够按某种次序排列;
- 三是ES6创造了一种新的遍历命令for...of循环。
- Iterator的遍历过程如下:
- 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
- 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
- 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
- 不断调用指针对象的next方法,直到它指向数据结构的结束位置。
4.1.2数据结构的默认Iterator接口
Iterator接口的目的,就是为所有数据结构提供了一种统一的访问机制,即for...of循环。
一种数据结构只要部署了Iterator接口,我们就称这种数据结构是”可遍历的“(iterable)。
ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性
ES6中,有三类数据结构原生具备Iterator接口:数组、某些类似数组的对象、Set和Map结构。
类似数组的对象(存在数值键名和length属性),如何部署Iterator接口?
Symbol.iterator方法直接引用数组的Iterator接口。
let iterable = { 0: 'a', 1: 'b', length: 2, [Symbol.iterator]: Array.prototype[Symbol.iterator] };
4.1.3调用Iterator接口的场合
(1)解构赋值
对数组和Set结构进行解构赋值时,会默认调用 Symbol.iterator 方法。
let [n1,n2,n3]=[1,3,"a"];
(2)扩展运算符
扩展运算符(...)也会调用默认的iterator接口。
var str = 'hello';
[...str] // ['h','e','l','l','o']
(3)yield*
yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。
let generator = function* () {
yield "a";
yield 2;
yield 5;
};
(4)其他场合
由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口。下面是一些例子:
- for...of
- Array.from()
- Map(), Set()(比如new Map([['a',1],['b',2]]))
4.1.4rest运算符与扩展运算符的区别
- 放在**被赋值**一方为**rest运算符**,放在**赋值一方**为**扩展运算符**。
- 三点放在**形参或者等号左边**为rest运算符;
- 放在**实参或者等号右边**为spread运算符
4.1.5遍历器对象的return()
- 具有next方法,还可以具有return方法
- return方法的使用场合是,如果for...of循环提前退出(通常是因为出错,或者有break语句或continue语句),就会调用return方法。
- 如果一个对象在完成遍历前,需要清理或释放资源,就可以部署return方法。
- 注意,return方法必须返回一个对象,这是Generator规格决定的。
4.16数组遍历语法的比较
- for循环 最原始的就是for循环
for(var i=0;i<10;i++){
console.log(i);
}
forEach 数组
数组提供内置的forEach方法,缺点是无法中途跳出forEach循环,break命令或return命令都不能奏效。
myArray.forEach(function (value) {
console.log(value);
});
for...in 遍历的是key
- for...in循环主要是为遍历对象而设计的,不适用于遍历数组。
for (let i of list) {
console.log( i );
}
for...of 遍历的是value
- 结论 有一些显著的优点
- 有着同for...in一样的简洁语法,但是没有for...in那些缺点。
- 不同用于forEach方法,它可以与break、continue和return配合使用。
- 提供了遍历所有数据结构的统一操作接口。