es6之Iterator和for...of循环

什么是Iterator(遍历器)

Iterator是一种机制,一种接口,为各类不一样的数据结构提供统一的访问机制。任何数据结构,只要部署Iterator接口,就能够完成遍历操做。遍历实际上是一种线性处理,有序的。数组

Iterator遍历的过程:bash

  • 一、建立一个遍历指针,指向当前数据结构的起始位置
  • 二、第一次调用指针对象的next方法,返回第一个成员
  • 三、第二次调用next方法,返回第二个成员
  • 四、不断的调用next方法,直到指针对象指向数据结构的结束位置
//获取遍历器
var arr = [1,2][Symbol.iterator]();

arr.next(); //{value: 1, done: false}
arr.next(); //{value: 2, done: false}
arr.next(); //{value: undefined, done: true}
arr.next(); //{value: undefined, done: true}
复制代码

返回的成员信息是一个对象,包含{value: any, done: boolean}。调用指针对象的next方法就能够遍历事先给定的数据结构。数据结构

因为Iterator只是把接口规范加到数据结构上,因此遍历器和所遍历的数据结构是分开的。函数

什么是遍历器生成函数

默认的Iterator接口部署在数据结构的Symbol.iterator属性上,属性对应的值就是遍历器生成函数,因此只要具备Symbol.iterator属性就能够遍历。若是Symbol.iterator方法反应的不是遍历器对象生成函数,就好报错。ui

执行Symbol.iterator属性就会返回一个遍历器对象。该对象的根本特征就是具备next方法,每次调用next就会返回一个表明当前成员的信息对象,具备value和done两个属性。spa

const obj = {
    a: 'aa',
    [Symbol.iterator]: function(){
        return {
            next(){
                return {
                    value: 1,
                    done: true,
                }
            }
        }
    }
}
var objIterator = obj[Symbol.iterator]();
objIterator.next(); //{value: 1, done: true}
objIterator.next(); //{value: 1, done: true}
复制代码

当使用for...of循环遍历某种数据结构时,就会自动去寻找Iterator接口设计

//无限循环,谨慎执行
for(let value of obj){
    console.log(value); //1
}
复制代码

原生具有Iterator接口的数据结构:指针

  • Array
  • Set
  • Map
  • String
  • TypeArray
  • 函数的argument对象
  • NodeList对象
  • Generator对象

对象(Object)没有Iterator接口,由于对象属性遍历前后顺序是不肯定的。code

Iterator接口与Generator函数

Symbol.iterator最简单的实现方式对象

var myIterator = {};
myIterator[Symbol.iterator] = function*(){
    yield 1;
    yield* [2, 3];
    yield 4;
}

[...myIterator] //[1,2,3,4]
复制代码

for...of循环与for..in循环的区别

一个数据结构只要部署了Symbol.iterator数据,就被视为具备Iterator接口,就可使用for...of循环它的成员。

for...of循环调用接口,数组的遍历接口只返回具备数字索引的属性。

var arr = [1,2];
a[3] = 3; 
arr.a = 'aa';

for(let value of arr){
    console.log(value);
}
// 1 2 empty 3

for(let value in arr){
    console.log(value);
}
// '0' '1' '3' 'aa'
复制代码

for...in循环遍历缺点:

  • 只能得到对象的键名,不能直接获取键值
  • 不只遍历数字键名,遍历手动添加的其余键名,甚至包括原型链上的键
  • 某些状况下以任意顺序遍历键名

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

for...of循环遍历优势:

  • 不一样于forEach方法,它能够与break、continue、return配合使用
  • 提供了遍历全部数据结构的统一接口
  • 对于字符串,能够识别32位UTF-16字符

for...of会把数组中空值也给遍历处理

对象的遍历,最好采用Object.keys + for...of

var obj = {
    a: 'aa',
    b: 'bb'
};

for(let key of Object.keys(obj)){
    console.log(key, obj[key])
}
//'a' 'aa'
//'b' 'bb'
复制代码
相关文章
相关标签/搜索