资讯专栏INFORMATION COLUMN

初入ES6-Generator和Iterator

waltr / 1371人阅读

摘要:根据百度百科的说法迭代器模式,又叫做游标模式。给出的定义为提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。从定义可见,迭代器模式是为容器而生。很明显,对容器对象的访问必然涉及到遍历算法。这两种情况好像都能够解决问题。

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

所以可以这样理解,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}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88835.html

相关文章

  • ES6-Generator与react状态机(13)

    摘要:同理,你只要知道改变状态能够实现要的功能,大体上的原理就是状态机就可以了。总结,本文重点状态机模式的使用场景,复杂多状态的管理,这里注意你没必要写个选项卡之类的用状态机,那反而是给自己找麻烦。 大家在写App和一些单页面程序的时候,经常会遇到这样的情况:showImg(https://segmentfault.com/img/bVbsNaA?w=240&h=427);当点击左边的箭头的...

    alphahans 评论0 收藏0
  • 初入ES6-Array

    摘要:用于将对象转为数组可遍历和类数组对象部署属性的对象和扩展运算符的区别是任何具有属性的都可以使用的方法是用原型该方法还有一个参数类似的新方法将字符串转化为数组,特别是大于的单个字符,避免分割成多个用来弥补构造函数的歧义三个空值只有一个参数其实 1,Array.from用于将对象转为数组(可遍历和类数组对象部署Iterator 属性的对象)和扩展运算符的区别是任何具有Length属性的都可...

    马永翠 评论0 收藏0
  • 初入ES6-解构

    摘要:允许按照一定的模式,从数组或者对象中取值,对变量进行赋值数组解构的对象要具有接口也就是可以遍历按照对应的关系进行取值如果解构不成功变量的值就是如果右侧的数值不是数组,就会报错注意字符串是可以遍历的也可以有默认值只要被赋值的变量不是严格就是默 ES6允许按照一定的模式,从数组或者对象中取值,对变量进行赋值 数组 var a = 2; var b = [1,2]; var c = this...

    FullStackDeveloper 评论0 收藏0
  • 初入ES6-letconst以及代码块

    摘要:变量和常量的声明一般的声明,不在函数内就是全局变量,值可以是基本和引用值,可以随时修改和删除语法同一个作用域的声明,只要有同样的声明都会报错,只能修改值语法,和一样,但是不能更改值以上两个语法都不存在变量提升的效果直接使用的话,直接引用错误 变量和常量的声明 var a = 34; //一般的声明,不在函数内就是全局变量,值可以是基本和引用值,可以随时修改和删除 ...

    wwolf 评论0 收藏0
  • HTML & CSS之小白初入江湖

    摘要:之小白初入江湖超文本标记语言简称是一种用于创建网页的标准标记语言。描述了一个网站的结构语义随着线索的呈现,使之成为一种标记语言而非编程语言。是块级元素,是行内元素。层叠样式表简称是一种用来为结构化文档如添加样式的工具。 HTML & CSS之小白初入江湖 1. HTML 超文本标记语言(HyperText Markup Language, 简称HTML)是一种用于创建网页的标准标记语言...

    fai1017 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<