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

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

(一)Iterator遍历器


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

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

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

.遍历器接口:

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

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

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

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

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

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

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

(1)数组

(2)某些类数组

(3)Map

(4)Set

var arr = [1,2,3,'aa','bb','cc'];
for(let elem of arr) {
  console.log(elem);
}
某些类数组: 
let obj = {
  data: ["aa","bb",'cc',3,9,8],
  [Symbol.iterator]() {
    const self = this;
    let index = 0;
    return {
      next() {
        if (index < self.data.length) {
          return {
            value: self.data[index++],
            done: false
          };
        } else {
          return { value: undefined, done: true };
        }
      }
    };
  }
};
let it = obj[Symbol.iterator]();
console.log(it.next().value)
复制代码

三、展开运算符:

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

代码实例如下:

let arr = ["源库网", 4, "www.yuankuwang.com"];
console.log(...arr);
复制代码

(二)Generator


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

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

【语法】

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

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

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

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

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

yield语句:

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

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

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

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

function *yuanku() {
  //console.log("欢迎来到" + yield "源库网");//报错
  console.log("欢迎来到" + (yield "源库网"));//正确
}
  let y = yuanku();
  console.log(y.next().value); //先返回yield
  console.log(y.next().value); //再返回return,yield为undefined
复制代码

next()方法:

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

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

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

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

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

function* yuanku(num) {
      let x = 2 * (yield num);
      console.log('x='+x);
      let y = yield x*3;
      console.log('y='+y);
      console.log(x,y);
    }
    var g=yuanku(5);
    console.log(g.next());//{value:5,done:false},第1个next传值无意义,因为没有上一个yield
    console.log(g.next());//x=NaN {value:NaN,done:false}
    console.log(g.next(3));//{value:12,done:false}
    console.log(g.next(3));//{value:undefined,done:true}
//-----------异步方法实测-------------------------
setTimeout(function () {
    console.log("hello");
  },3000);
let y;
   var func = function(time) {
      setTimeout(function() {
          console.log(time, "  on");
          y.next(true);
      }, time);
    };
    var gen = function * () {
        var f1 = yield func(3000);
        console.log('f1:', f1);
        var f2 = yield func(1000);
        console.log('f2:', f2);
    };
    y = gen();
    y.next();
console.log('end');
复制代码

a242acdc3610c3400252fdac29230c0.png


作者:zhulin1028

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章
|
网络虚拟化
VLAN(虚拟局域网)简介与配置指南
VLAN(虚拟局域网)简介与配置指南
910 1
|
安全 网络协议 网络安全
网站被攻击了该怎么办?如何恢复网站,如何避免网站被攻击?
网站被攻击了该怎么办?如何恢复网站,如何避免网站被攻击?
|
Rust 安全 算法
揭秘Rust语言如何重塑区块链安全:打造坚不可摧的分布式账本新篇章!
【8月更文挑战第31天】自比特币诞生以来,区块链技术凭借其去中心化和不可篡改的特点备受关注。为了应对安全性挑战,Rust 语言凭借其内存安全特性逐渐成为区块链开发的优选。本文探讨了 Rust 如何助力区块链实现更安全的分布式账本。通过示例展示了 Rust 在避免内存泄漏、空指针引用及数据竞争等方面的优势,预示着 Rust 在高性能、高安全性需求的区块链应用中拥有广阔前景。
386 2
|
机器学习/深度学习 人工智能 自然语言处理
AI技术对法律行业有何影响?
【6月更文挑战第27天】AI技术对法律行业有何影响?
641 3
|
应用服务中间件 nginx
Nginx反向代理其他服务
Nginx反向代理其他服务
|
12月前
|
存储 传感器 人工智能
「AI实践派」产品生态伙伴Zilliz联合活动
阿里云与向量搜索领域明星企业Zilliz将在杭州阿里巴巴西溪园区共同举办“中外AI产品应用实践和出海实战”分享沙龙。
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
214 3
|
存储 运维 安全
Greenplum闭源?平滑迁移到 AnalyticDB 开启Data+AI新范式
知名开源 MPP 数据库 Greenplum 由于其丰富的企业级特性和出色的数据处理能力成为很多企业构建数仓的首选。近期 GP 公开 Github 仓库无法访问仅保留只读归档代码,业界纷纷猜测 GP 即将闭源。云原生数仓 AnalyticDB PostgreSQL 版完全掌控内核代码,完全兼容GP语法,全自研计算及存储引擎较比开源GP有五倍性能提升,全自研企业级特性在实时计算、弹性扩展、安全增强、高可用等方面实现对GP的全面超越,并在数仓能力上扩展了向量检索及一站式 RAG 服务,帮助企业快速构建 AI 应用、开启 Data+AI 新范式。
59603 3
|
Dart JavaScript 安全

热门文章

最新文章