Iterator接口(遍历器)和for/of循环

在javascript中表示“集合”的数据结构,主要有Array,Object,Map,Set。

Iterator(遍历器)接口是为各种不同的数据结构提供了统一的访问机制。任何数据结构具有Iterator接口,就可以完成遍历操作(依次排序进行遍历)。

Iterator遍历的过程:

创建一个指针对象,指向数据结构的初始位置——调用指针对象的next方法,指向数据结构成员——不断调用next方法,直到指向数据结构的结束位置。

var it = makeIterator(['a','b']);

function makeIterator(array){
   var nextIndex = 0;
   return{
       next:function(){
           return nextIndex < array.length ? 
           {value:array[nextIndex++],done:false} : 
           {value:undefined,done:true}
       }
   }
}

it.next() 

默认的Iterator接口
Iterator借口的目的在于:为所有数据结构,提供统一的访问机制。即用for/of循环,当使用for/of进行遍历的时候,该循环会自动去寻找Iterator接口。

默认的Iterator接口部署在数据结构的Symbol.iterator属性,一个数据结构只要有Symbol.Iterator属性,就是“可遍历的”,Symbol.iterator属性本身是一个函数,执行这个函数,返回 一个遍历器。

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

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

let arr = [1,2,3,4,5]
let iter = arr[Symbol.iterator]();
iter.next()

一个对象具备Iterator接口,必须在Symbol.iterator的属性上部署遍历器生成方法(原型链上的对象具有该方法也可)

 

 

只要某个数据结构部署了Iterator接口,就可以使用拓展运算符将其转化为数组。

let arr = [...iterator];

var str = 'hello';
[...str]  //["h", "e", "l", "l", "o"]

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

let generator = function* (){
    yield 1;
    yield* [2,3,4];
    yield 5;
}
var it = generator();
it.next();  //{value: 1, done: false}
it.next()   //{value: 2, done: false}
it.next()   //{value: 3, done: false}
it.next()   //{value: 4, done: false}
it.next()   //{value: 5, done: false}
it.next()   //{value: undefined, done: true}

数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了Iterator接口,如下:

for/of    Array.from()   Map()    Set()   WeakMap()   WeakSet()  Promise.all()  Promise.rece()

 

1,字符串的Iterator接口

var str = 'hi';
typeof str[Symbol.iterator]    //'function'

var a = str[Symbol.iterator]();
a.next()   //{value: "h", done: false}
a.next()   //{value: "i", done: false}

[...str]     //["h", "i"]

以前字符串转化为数组:str.split(""),ES6中可以使用Iterator进行遍历加入数组中,相当简洁。

 这里写一个能用for/of进行遍历对象的方法键值的方法:

 

function* entries(obj) {
  for (let key of Object.keys(obj)) {
    yield [key, obj[key]];
  }
}

for (let [key, value] of entries(obj)) {
  console.log(key, '->', value);
}
// a -> 1
// b -> 2
// c -> 3

 

其他遍历方法的比较:

forEach内部写break命令不奏效,会报错,return语句是可以写的。

for/in是用来遍历对象的键名,数组的索引,主要适用于遍历对象。

for/of主要是用来遍历数组的值,可以搭配break,continue,return等,提供了遍历所有数据结构的统一操作接口。

 

posted @ 2018-05-16 15:55  tangjiao_Miya  阅读(860)  评论(0编辑  收藏  举报