ES6新特性(4)之Iterator遍历器/Generator

举报
zhulin1028 发表于 2022/04/15 01:17:35 2022/04/15
【摘要】  目录 (一)Iterator遍历器 (二)Generator (一)Iterator遍历器 遍历器是一种接口,它为不同的数据结构提供了统一的访问机制。  如果一个数据结构具有遍历器接口,那么就可以依次处理该数据结构的成员。  当前javascript用来表示集合的数据结构有四种,分别...

 目录

(一)Iterator遍历器

(二)Generator


(一)Iterator遍历器

遍历器是一种接口,它为不同的数据结构提供了统一的访问机制。 

如果一个数据结构具有遍历器接口,那么就可以依次处理该数据结构的成员。 

当前javascript用来表示集合的数据结构有四种,分别是数组、对象、Set和Map,并且这四种数据结构可以相互嵌套使用,比如数组的成员可以是对象,对象的成员又可以是Set等等。

.遍历器接口:

如果一个结构具有Symbol.iterator属性,那么就称这个数据结构具有遍历器接口。

Symbol.iterator返回Symbol对象的iterator属性,这是一个预定义好的、类型为Symbol的特殊值。

Symbol.iterator属性指向一个方法,调用此方法返回一个遍历器对象,它是一个指针对象,默认指向数据结构的起始位置。


  
  1. let arr = ["源库网", 4, "www.yuankuwang.com", "北京大学"];
  2. let it = arr[Symbol.iterator]();
  3. console.log(it.next());
  4. console.log(it.next());
  5. console.log(it.next());
  6. //搞笑遍历
  7. let arr = ["源库网", 4, "北京大学"];
  8. let it = arr[Symbol.iterator]();
  9. //循环器(效率高)
  10. for(;;) {
  11. let nextEle = it.next();
  12. if(nextEle.done) {
  13. break
  14. }
  15. console.log(nextEle.value);
  16. }
  17. //每一次调用next()方法都会返回一个对象,此对象包含value和done属性,value属性值是数据结构成员的值,如果遍历完成value属性值为undefined;done属性是一个布尔值,如果为true,说明遍历完成,如果为false,说明遍历尚未完成

.默认具有遍历器接口的数据结构,for of循环

当对一个数据结构使用for of循环遍历的时候,会自动调用遍历器接口。

ES6中有四类数据结构默认具有遍历器接口:

(1)数组

(2)某些类数组

(3)Map

(4)Set


  
  1. var arr = [1,2,3,'aa','bb','cc'];
  2. for(let elem of arr) {
  3.   console.log(elem);
  4. }
  5. 某些类数组: 
  6. let obj = {
  7.   data: ["aa","bb",'cc',3,9,8],
  8.   [Symbol.iterator]() {
  9.     const self = this;
  10.     let index = 0;
  11.     return {
  12.       next() {
  13.         if (index < self.data.length) {
  14.           return {
  15.             value: self.data[index++],
  16.             done: false
  17.           };
  18.         } else {
  19.           return { value: undefined, done: true };
  20.         }
  21.       }
  22.     };
  23.   }
  24. };
  25. let it = obj[Symbol.iterator]();
  26. console.log(it.next().value)

三、展开运算符:

如果一个数据结构具有遍历器接口,那么除了可以使用for of循环以外,也可以使用展开运算符。

代码实例如下:


  
  1. let arr = ["源库网", 4, "www.yuankuwang.com"];
  2. console.log(...arr);

(二)Generator

Generator函数是ES6新增的一种异步编程方案。

说明:Generator函数指的是一种新的语法结构,是一个遍历器对象生成器,它内部可以封装多个状态,非常适合用于异步操作

【语法】

Generator函数语法和普通的function函数类似,但是有三个不同点:

(1)function关键字和函数名称之间有一个星号(*)。

(2)函数体内可以使用yield语句。

(3)函数调用后不会立即执行,返回的是一个遍历器对象。


  
  1. //一个Generator函数
  2. function* yuanku() {
  3.   yield "源库网";
  4.   yield "北京海淀";
  5.   yield "www.yuankuwang.com";
  6.   return "end";  
  7. }
  8. //函数内部使用yield语句定义不同的状态,return也可以定义一个状态,也就是说上面代码有四个状态
  9. var y = yuanku(); //调用此函数,并不会立即执行它其中的代码,而是返回一个遍历器对象
  10. console.log(y.next()); //返回一个具有value和done属性的对象
  11. console.log(y.next()); //有return,返回{value:end,done:true};如果没有return,返回{value: undefined, done: true}

yield语句:

每一个yield语句定义不同的状态,它也是一个代码执行暂停标识。

yield语句不能在普通函数中使用,否则会报错。

调用Generator函数可以返回一个遍历器对象,要想访问Generator函数中的每一个状态,需要使用遍历器对象调用next()方法。

如果yield语句作为其他语句的一部分,那么必须使用小括号包裹,否则会报错


  
  1. function *yuanku() {
  2.   //console.log("欢迎来到" + yield "源库网");//报错
  3.   console.log("欢迎来到" + (yield "源库网"));//正确
  4. }
  5.   let y = yuanku();
  6.   console.log(y.next().value); //先返回yield
  7.   console.log(y.next().value); //再返回return,yield为undefined

next()方法:

next()一个主要功能,就是从暂停状态继续下一段代码的执行。

next()还有一个重要的功能,那就是可以接受一个参数,此参数作为上一个yield语句的返回值。

虽然当代码执行到yield语句的时候,能够将其后面的表达式的值作为对象的value属性值,但是默认情况下yield语句是没有返回值的,或者说它的返回值是undefined

注意:yield语句的返回值和yield后面表达式的返回值是两个概念

向next中传值,!!!此值作为上一个yield的返回值!!!


  
  1. function* yuanku(num) {
  2.       let x = 2 * (yield num);
  3.       console.log('x='+x);
  4.       let y = yield x*3;
  5.       console.log('y='+y);
  6.       console.log(x,y);
  7.     }
  8.     var g=yuanku(5);
  9.     console.log(g.next());//{value:5,done:false},第1个next传值无意义,因为没有上一个yield
  10.     console.log(g.next());//x=NaN {value:NaN,done:false}
  11.     console.log(g.next(3));//{value:12,done:false}
  12.     console.log(g.next(3));//{value:undefined,done:true}
  13. //-----------异步方法实测-------------------------
  14. setTimeout(function () {
  15.     console.log("hello");
  16.   },3000);
  17. let y;
  18.    var func = function(time) {
  19.       setTimeout(function() {
  20.           console.log(time, "  on");
  21.           y.next(true);
  22.       }, time);
  23.     };
  24.     var gen = function * () {
  25.         var f1 = yield func(3000);
  26.         console.log('f1:', f1);
  27.         var f2 = yield func(1000);
  28.         console.log('f2:', f2);
  29.     };
  30.     y = gen();
  31.     y.next();
  32. console.log('end');

 

文章来源: zhulin1028.blog.csdn.net,作者:zhulin1028,版权归原作者所有,如需转载,请联系作者。

原文链接:zhulin1028.blog.csdn.net/article/details/123967549

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。