Iterator
根据百度百科的说法:

迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。 从定义可见,迭代器模式是为容器而生。很明显,对容器对象的访问必然涉及到遍历算法。你可以一股脑的将遍历方法塞到容器对象中去;或者根本不去提供什么遍历算法,让使用容器的人自己去实现去吧。这两种情况好像都能够解决问题。

类似之前的链表结构,每个对象不仅包含自身的值,也包含下一个变量的指针;

function Chan(value){
    this.value = value;
    this.next = null;
};
var newObj = new Chan();        //对象都有两个属性

创建迭代器

function creatIterator(items){
    var i = 0;
    var next = function(){
        var done =( i>=items.length);            //判断itmes的数量是否是最后一个,如果是done = true;那么value = undefined;
        var value = !done?items[i++]:undefined;            //
        return {
            value : value,
            done : done
        };
    }
    return {next : next};
};
var iterator = new creatIterator([3,3,2,6,7]);
iterator.next()  ->{value : 3,done:false;}
iterator.next()  ->{value : 3,done:false;}
iterator.next()  ->{value : 2,done:false;}
iterator.next()  ->{value : 6,done:false;}
iterator.next()  ->{value : 7,done:false;}
iterator.next()  ->{value :undefined,done:true;}        //后面执行的都是一样
//或者省略最后一步;
function creatIterator(items){
    var i = 0;
    return {
        next : function(){
            return i<items.length?{
                value : array[i++]
            }:{
                done :true
            };
        }
    }
}

所以可以这样理解,Iterator就是一个特殊的对象,这个对象可以访问一个容器对象(包含很多无序的变量属性等),每次调用next就返回一个对象,直到最后一个,有些方法调用是自动连续的调用,见生成器函数只要有这个接口就可以将返回的对象用扩展运算符...转换为数组并且可以使用数组的方法
有三种数据结构具有原生的Iterator接口,可以直接用for..of 遍历,这三种数结构内置了三个迭代器
entries()返回数组,keys(),values();针对不同的数据结构,都有默认的迭代器,注意不同的浏览器支持的成都不一样;
1,Array

2,Map
图片描述

3,Set
图片描述
一些类数组的对象(有数字属性,和length的属性)也具有Iterator 的接口。比如字符串对象
图片描述

Iterator应用场合
1,解构赋值

var  arr = [1,2,3,4,5];
var arr1 = [...arr];
console.dir(arr1)    //[1, 2, 3, 4, 5]

2,扩展运算符,同上;
3,特殊场合

//for...of;如果数组有非数字键名的话不可遍历,arr.name = 'obama'
var  arr = [1,2,3,4,'a','b'];
var obj = {name : 'obama',1 : 2}
for( pro in arr){console.log(pro)}    //0,,,,5只是得到键名;
for( pro in obj){console.log(pro)}  //得到所有的属性名
for( pro of o arr){console.log(pro)}  //输出所有的属性
for( pro of obj){console.log(pro)}      //报错,对象不可遍历
//Array...from;
//Map(),Set()参数对象
//Promise.all(),race()

Generator生成器函数;
有三个属性next,throw,return ;

function *fnName(){    //函数名字前必须有星号;

    yield 'first';    //每次执行后都从下一个yield关键字开始,直到最后的return;
    yield 'second';    //yield 只能用在生成器函数内部,其他 的会报错
    return 'all done';
}
var ob = fnName()        //和普通函数一样的调用
ob.next()    //
ob.next()    //
ob.next()    //每次调用都返回一个对象
//每个生成器函数都有Iterator方法并且返回自身
ob[Symbol.iteraro]() === ob;



//1,next()的方法;
//yied和return 一样没有返回值,或者是undefined;
function *fn(){
    var num  = yield 4;
    console.log(num);
    
}
var s = fn();
s.next();    //{value: 4, done: false}
s.next()    //undefined;{value: undefined, done: true};
//next()的参数,可以明确的设定上一次yield的返回值(如果已经是最后的话,就没有作用)
s.next(23);    //value : 23,

//生成器函数的遍历for of ... 解构赋值,Array.from都会自动遍历,不需要调用next方法
function *test(){
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    return 5;
}
var te = test();
for( v of te){console.log(v)}    //1,2,3,4
te.next();//{value: undefined, done: true}已经循环完毕
//2,throw方法
//3,return 方法    //直接终止遍历
function *test(){
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    return 5;
};
var s = test();
s.next();//value:1,done:false;
s.turn ();value:undefined,done:ture;    //
s.next();//value:1,done:false;
 //yield*语句
function *boo(){
    yield 1;
    yield 2;
}  ;
function *bar(){
    yield 3;
    yield boo();
} 
var s = bar();
s.next();//{value: 3, done: false}
s.next();//{value: boo, done: false}没有执行
//使用yield *boo();表明返回的是一个遍历器对象,可以是数组等其他对象

//{value: 1, done: false}

scupture
35 声望1 粉丝

var me = 'missing you';


« 上一篇
初入ES6-Symbol
下一篇 »
初入ES6-Array