Iterator

Posted Beat Yourself

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Iterator相关的知识,希望对你有一定的参考价值。

一、概述

  1、一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作

  2、调用指针对象的next方法,就可以遍历事先给定的数据结构

  3、每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含valuedone两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

  4、凡是部署了Symbol.iterator属性的数据结构,就称为部署了遍历器接口。调用这个接口,就会返回一个遍历器对象。

二、数据结构的默认Iterator接口

  1、对象的Symbol.iterator属性,指向该对象的默认遍历器方法。

  2、具备Iterator接口的原生数据结构:

  •   数组
  •   某些类似数组的对象
  •   Set和Map结构。

  3、其他数据结构(主要是对象)的Iterator接口,都需要自己在Symbol.iterator属性上面部署,这样才会被for...of循环遍历

  4、严格地说,对象部署遍历器接口并不是很必要,因为这时对象实际上被当作Map结构使用

  5、对一般对象部署迭代器对象:

/**
 * 
 * @authors Soul (2461358597@qq.com)
 * @date    2016-06-01 15:34:02
 * @version 0.0.1
 * @description  给一般对象部署迭代器对象
 */
 
//迭代器对象
const soul_iterator={
        soul_index:-1,
        [Symbol.iterator](){
            return this;
        },
        next(){
            var arr=this.soul_exchange();
            this.soul_index++;
            return this.soul_index>=arr.length?{value:undefined,done:true}:{value:this[arr[this.soul_index]],done:false};
        },
        soul_exchange(){
            var array=[];//用来存放数字索引和属性名的键值对
            var j=0;//用作array数组的索引值
            for(let i in this){
                if(i!="soul_index"&&i!="next"&&i!="soul_exchange")
                    array[j++]=i;
            }
            // console.log(array);
            return array;
        }
};

//测试对象
function objTest(){}
objTest.prototype={
    name:"soul",
    age:21    
};

//部署迭代器对象
objTest.prototype.__proto__=soul_iterator;

//创建测试对象的实例
var newObj=new objTest();

// for...of  测试
for(let i of newObj){
    console.log(i);
}

//next()方法测试
// console.log(newObj.next());
// console.log(newObj.next());
// console.log(newObj.next());
// console.log(newObj.next());

 

 

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

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

  7、如果Symbol.iterator方法对应的不是遍历器生成函数(即会返回一个遍历器对象),解释引擎将会报错

三、调用Iterator接口的场合

  1、默认调用Iterator接口的情况:

  • 解构赋值
  • 扩展运算符  //只要某个数据结构部署了Iterator接口,就可以对它使用扩展运算符,将其转为数组
  • yield*  //yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口
  • for...of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()(比如new Map([[\'a\',1],[\'b\',2]])
  • Promise.all()
  • Promise.race()

四、字符串的Iterator接口

  1、字符串是一个类似数组的对象,也原生具有Iterator接口。

五、Iterator接口和Generator函数

  1、Generator可以很容易的实现Iterator接口

  2、实现方式:

var myIterable = {};

myIterable[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};

  3、yield命令给出每一步的返回值。

六、Iterator对象的return()和throw()

  1、next方法是必须部署的,return方法和throw方法是否部署是可选的

  2、return方法必须返回一个对象

  3、return方法主要用于提前退出

  4、throw方法主要是配合Generator函数使用,一般的遍历器对象用不到这个方法

七、for...of

  1、凡是部署了Iterator对象的对象,都可以使用for...of取得值

 

以上是关于Iterator的主要内容,如果未能解决你的问题,请参考以下文章

C++中的QHashIterator

RecursiveDirectoryIterator() 不显示空目录

eclipse中如何自动生成iterator遍历代码块吗?

使用Kotlin中的foreach循环遍历BigInteger值

iterator

Java iterator()和next()原理用法