ES6躬行记(18)——迭代器

简介:   ES6将迭代器和生成器内置到语言中,不仅简化了数据处理和集合操作,还弥补了for、while等普通循环的不足,例如难以遍历无穷集合或自定义的树结构等。

  ES6将迭代器和生成器内置到语言中,不仅简化了数据处理和集合操作,还弥补了for、while等普通循环的不足,例如难以遍历无穷集合或自定义的树结构等。

  迭代器(Iterator)是一种用于迭代的对象,可有序的依次访问集合中的数据项。ES6制订了一套标准化的迭代器接口(包含3个方法,如表11所列),只要实现了这套接口都能成为迭代器。


表11 迭代器接口

方法 返回值 描述
next() IteratorResult 必选,获取下一个迭代器结果
return() IteratorResult 可选,停止迭代并返回一个迭代器结果
throw() IteratorResult 可选,抛出错误并返回一个迭代器结果


  上表中的IteratorResult也叫迭代器结果,是一个特定形式的对象,它必须包含两个属性:value和done。value属性就是集合成员的值,done属性是一个布尔值,用于标记当前迭代是否结束。下面是一个简单的迭代器示例。


function createIterator(items) {
  var index = 0;
  return {
    next() {
      var done = index >= items.length;
      return { value: items[index++], done: done };
    }
  };
}
var iterator = createIterator(["a", "b"]);
iterator.next();        //{value: "a", done: false}
iterator.next();        //{value: "b", done: false}
iterator.next();        //{value: undefined, done: true}


  当迭代结束时,done属性的值将会是true,而value属性在未提供返回值的时候就会设为undefined。


一、可迭代对象


  包含Symbol.iterator属性的对象被称为可迭代对象(Iterable),Symbol.iterator是一个特殊的内置符号(详见第6篇),它的值是一个返回迭代器的方法。ES6内置了多种可迭代对象,例如集合(Array、TypedArray、Set和Map)、类数组对象(Arguments和NodeList)、字符串等,它们都含有各自默认的迭代器。下面的示例使用了数组的默认迭代器,通过next()方法依次遍历了它所包含的元素,返回结果与上一个示例类似。

var arr = ["a", "b"],
  iterator = arr[Symbol.iterator]();
iterator.next();        //{value: "a", done: false}
iterator.next();        //{value: "b", done: false}
iterator.next();        //{value: undefined, done: true}

  可迭代对象的应用场景在前面的章节中已陆续介绍过,例如第2篇的扩展运算符、第3篇的解构赋值和第12篇的Array.from()方法等。在接下来的章节中,还会将可迭代对象应用于for-of循环和yield*。


二、for-of


  这是ES6新增的一种循环语句,当要遍历一个可迭代对象时,会先通过它的Symbol.iterator属性得到默认迭代器,再调用迭代器的next()方法,读取IteratorResult的value属性的值并赋给for-of语句中声明的变量,如此反复,直到done属性为ture时才终止遍历。而和其它循环语句一样,for-of循环也能通过跳转语句return、break和continue提前终止。下面分别对Set和Map两种数据结构进行for-of循环。


var set = new Set(["strick", 28]),
  map = new Map([["name", "strick"], ["age", 28]]);
/********************
  "strick"
  28
********************/
for (var value of set) {
  console.log(value);
}
/********************
  "name" "strick"
  "age" 28
********************/
for (var [key, value] of map) {
  console.log(key, value);
}


  在前文中曾多次提到过3个迭代器方法,根据上面代码的输出结果可知,Set和Map的默认迭代器分别通过values()和entries()方法获得。


三、字符串


  字符串虽然是基础类型,但它能被隐式的封装成String对象,而String含有默认迭代器,因此可以进行for-of循环。在第9篇字符串中曾提到过,JavaScript采用了UTF-16编码的Unicode字符集,在BMP中的字符可用一个编码单元表示,而在辅助平面中的字符则需要两个编码单元。以“向”和“𠮳”为例,前者存在于BMP中,后者存在于辅助平面中,当用for循环遍历下面的这段字符串(str)时,无法得到正确的字符。

var str = "向𠮳";        //str.length的值为3
for (var i = 0; i < str.length; i++) {
  console.log(str[i]);
}

  而在改用for-of循环后(如下代码所示),就能得到预期的结果。由此可见,迭代器在处理字符串时更加安全可靠。

for (var value of str) {
  console.log(value);
}


四、创建可迭代对象


  普通的对象只要包含Symbol.iterator属性,并返回一个迭代器,就能摇身一变成为可迭代对象。在下面的代码中,iterable对象本身就是迭代器,因此Symbol.iterator属性的返回值可以是当前对象。注意,必须返回迭代器,否则会出现不可预料的错误。


var iterable = {
  items: ["a", "b"],
  index: 0,
  [Symbol.iterator]() {
    return this;
  },
  next() {
    var done = this.index >= this.items.length;
    return { value: this.items[this.index++], done: done };
  },
  return() {
    return { value: undefined, done: true };
  }
};


  在iterable对象中,包含return()方法,只有当迭代器终止遍历时,才会触发此方法。例如在for-of循环体中执行break、continue或return语句,甚至还能通过调用throw语句抛出自定义异常,提前结束代码的运行,以此实现触发条件,如下所示。

for (var value of iterable) {
  throw new Error();
}

 

相关文章
ly~
|
存储 安全 大数据
数据库的发展趋势是什么?
数据库发展趋势涵盖云化、智能化、分布式及多模型融合等多个方面。云数据库和DBaaS模式使企业能快速调整资源,降低成本;AI和机器学习技术推动智能运维、查询优化等功能;分布式架构和并行计算则提升了数据处理能力和速度。此外,多模型数据库满足了多样化的数据处理需求,而数据安全技术和隐私保护也在不断加强。数据库与大数据、AI、区块链等新兴技术的融合将进一步提升其功能与安全性。
ly~
946 1
|
数据采集 关系型数据库 MySQL
切割字符串:深入了解MySQL中的SUBSTRING()函数
在数据库操作中,提取字符串的一部分是常见的需求,这时可以使用MySQL中的SUBSTRING()函数。本文将深入探讨SUBSTRING()函数的用法、示例以及在数据库操作中的应用。
1168 0
|
存储 Python
Python中的布尔数据类型:深入探索与应用
Python中的布尔数据类型:深入探索与应用
597 5
|
负载均衡 Java Apache
【微服务系列笔记】Feign
Feign是一个声明式的伪HTTP客户端,它使得HTTP请求变得更简单。使用Feign,只需要创建一个接口并注解。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。 OpenFeign 是SpringCloud在Feign的基础上支持了SpringMVC的注解。
376 8
|
SQL 关系型数据库 MySQL
OceanBase 的 SQL 兼容性与优化
【8月更文第31天】随着分布式计算的发展,越来越多的企业开始采用分布式数据库来满足其大规模数据存储和处理的需求。OceanBase 作为一款高性能的分布式关系数据库,其设计旨在为用户提供与传统单机数据库类似的 SQL 查询体验,同时保持高可用性和水平扩展能力。本文将深入探讨 OceanBase 的 SQL 引擎特性、兼容性问题,并提供一些针对特定查询进行优化的方法和代码示例。
949 0
|
监控 安全 网络协议
关于HTTP劫持,如何理解、防范与应对
**HTTP劫持详解:原理、危害与对策** HTTP劫持是中间人攻击,通过拦截未加密的HTTP通信窃取信息。危害包括信息泄露、恶意软件传播和内容篡改。常见形式有代理服务器、会话、DNS劫持及恶意软件。检测方法包括检查网络、观察浏览器行为、使用安全工具及报告问题。 防范措施包括使用HTTPS、验证TLS/SSL证书、避免不安全Wi-Fi、启用HSTS、设置CSP、更新软件、使用WAF、加密DNS及监控日志。德迅云安全提供实战化安全产品,如安全加速CSDN,防御Web攻击,保障业务安全和快速访问。保持安全意识和更新防护策略至关重要。
|
编解码 Java
请求参数中文乱码-POST解决方法
请求参数中文乱码-POST解决方法
|
JSON Java 关系型数据库
【Feign】 基于 Feign 远程调用、 自定义配置、性能优化、实现 Feign 最佳实践
【Feign】 基于 Feign 远程调用、 自定义配置、性能优化、实现 Feign 最佳实践
716 0
|
SQL 存储 分布式计算
MaxCompute 入门:大数据处理的第一步
【8月更文第31天】在当今数字化转型的时代,企业和组织每天都在产生大量的数据。有效地管理和分析这些数据变得至关重要。阿里云的 MaxCompute(原名 ODPS)是一个用于处理海量数据的大规模分布式计算服务。它提供了强大的存储能力以及丰富的数据处理功能,让开发者能够快速构建数据仓库、实时报表系统、数据挖掘等应用。本文将介绍 MaxCompute 的基本概念、架构,并演示如何开始使用这一大数据处理平台。
1860 0
|
关系型数据库 MySQL 数据库
MySQL8.0.36 安装配置教程(保姆级,包含图文讲解,环境变量的配置)适合小白
MySQL8.0.36 安装配置教程(保姆级,包含图文讲解,环境变量的配置)适合小白