欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ES6看完必会第十三章------ Iterator(遍历器)(可私信解惑,不会来捶我)

程序员文章站 2022-07-16 22:05:08
...

Iterator(遍历器)的概念

遍历器(Iterator)是一种接口,为了各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

 

Iterator的作用有三个:

 

  • 一是为各种数据结构,提供一个统一的、简便的访问接口;
  • 二是使得数据结构的成员能够按某种次序排列;
  • 三是ES6创造了一种新的遍历命令for...of循环。

 

Iterator的遍历过程如下:

 

  1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

数据结构的默认Iterator接口

Iterator接口的目的,就是为所有数据结构提供了一种统一的访问机制,即for...of循环。当使用for...of循环遍历某种数据结构时,该循环会自动去寻找Iterator接口。

一种数据结构只要部署了Iterator接口,我们就称这种数据结构是”可遍历的“(iterable)。

ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。

在ES6中,有三类数据结构原生具备Iterator接口:数组、某些类似数组的对象、Set和Map结构。for...of循环会自动遍历它们。

 

对于类似数组的对象(存在数值键名length属性),部署Iterator接口,有一个简便方法,就是Symbol.iterator方法直接引用数组的Iterator接口。

let iterable = {
  0: 'a',
  1: 'b',
  length: 2,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};

调用Iterator接口的场合

有一些场合会默认调用Iterator接口(即Symbol.iterator方法),除了for...of循环以外,还有几个别的场合会调用该接口。

(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]]))

遍历器对象的return()

遍历器对象除了具有next方法,还可以具有return方法。

return方法的使用场合是,如果for...of循环提前退出(通常是因为出错,或者有break语句或continue语句),就会调用return方法。如果一个对象在完成遍历前,需要清理或释放资源,就可以部署return方法。

function foo(file) {
    return {
        next() {          //  next方法    
        },
        return() {      //	return方法
        },
     };
}

注意,return方法必须返回一个对象,这是Generator规格决定的。

 

数组遍历语法的比较

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循环是以字符串作为键名“0”、“1”、“2”等等。

for...in循环主要是为遍历对象而设计的,不适用于遍历数组。

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

for...of

遍历的是value。

for ...of 循环相比上面几种做法,有一些显著的优点。

  • 有着同for...in一样的简洁语法,但是没有for...in那些缺点。
  • 不同用于forEach方法,它可以与break、continue和return配合使用。
  • 提供了遍历所有数据结构的统一操作接口。
for (var n of list ) {
    if (n > 1000)
        break;
    console.log(n);
}

 

相关标签: ES6快速入门 ES6

上一篇: es6中的类

下一篇: 2.ES6-新特性