首页 web前端 js教程 ES6可迭代协议和迭代器协议详解

ES6可迭代协议和迭代器协议详解

Jan 15, 2018 am 09:10 AM
协议 详解

本文主要介绍了详解ES6语法之可迭代协议和迭代器协议,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

ECMAScript 2015的几个补充,并不是新的内置或语法,而是协议。这些协议可以被任何遵循某些约定的对象来实现。
有两个协议:可迭代协议和迭代器协议。

可迭代协议

可迭代协议允许 JavaScript 对象去定义或定制它们的迭代行为, 例如(定义)在一个 for..of 结构中什么值可以被循环(得到)。一些内置类型都是内置的可迭代对象并且有默认的迭代行为, 比如 Array or Map, 另一些类型则不是 (比如Object) 。

Iterator 接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for...of循环(详见下文)。当使用for...of循环遍历某种数据结构时,该循环会自动去寻找 Iterator 接口,调用Symbol.iterator方法,返回该对象的默认遍历器。

ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可迭代的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。

为了变成可迭代对象, 一个对象必须实现(或者它原型链的某个对象)必须有一个名字是 Symbol.iterator 的属性:

迭代器协议

该迭代器协议定义了一种标准的方式来产生一个有限或无限序列的值。

JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set。这样就有了四种数据集合,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象。这样就需要一种统一的接口机制,来处理所有不同的数据结构。

迭代器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。

Iterator 的遍历过程是这样的。

  1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。


var someString = "hi";
typeof someString[Symbol.iterator]; // "function"
var iterator = someString[Symbol.iterator]();
iterator + "";  // "[object String Iterator]"
iterator.next()    // { value: "h", done: false }
iterator.next();   // { value: "i", done: false }
iterator.next();   // { value: undefined, done: true }
登录后复制

原生具备 Iterator 接口的数据结构如下。

  1. Array

  2. Map

  3. Set

  4. String

  5. TypedArray

  6. 函数的 arguments 对象

  7. NodeList 对象

注意对象是不具备 Iterator 接口的,一个对象如果要具备可被for...of循环调用的 Iterator 接口,就必须在Symbol.iterator的属性上部署遍历器生成方法(原型链上的对象具有该方法也可)。

调用 Iterator 接口的场合

有一些场合会默认调用 Iterator 接口(即Symbol.iterator方法),除了下文会介绍的for...of循环,解构赋值, 扩展运算符其实也会调用默认的Iterator 接口。

实际上,这提供了一种简便机制,可以将任何部署了 Iterator 接口的数据结构,转为数组。也就是说,只要某个数据结构部署了 Iterator 接口,就可以对它使用扩展运算符,将其转为数组。

由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口。下面是一些例子。

  1. for...of

  2. Array.from()

  3. Map(), Set(), WeakMap(), WeakSet()(比如new Map([['a',1],['b',2]]))

  4. Promise.all()

  5. Promise.race()

for...of

for...of 循环是最新添加到 JavaScript 循环系列中的循环。

它结合了其兄弟循环形式 for 循环和 for...in 循环的优势,可以循环任何可迭代(也就是遵守可迭代协议)类型的数据。默认情况下,包含以下数据类型:String、Array、Map 和 Set,注意不包含 Object 数据类型(即 {})。默认情况下,对象不可迭代。

在研究 for...of 循环之前,先快速了解下其他 for 循环,看看它们有哪些不足之处。

for 循环

for 循环的最大缺点是需要跟踪计数器和退出条件。我们使用变量 i 作为计数器来跟踪循环并访问数组中的值。我们还使用 Array.length 来判断循环的退出条件。

虽然 for 循环在循环数组时的确具有优势,但是某些数据结构不是数组,因此并非始终适合使用 loop 循环。

for...in 循环

for...in 循环改善了 for 循环的不足之处,它消除了计数器逻辑和退出条件。但是依然需要使用 index 来访问数组的值.

此外,当你需要向数组中添加额外的方法(或另一个对象)时,for...in 循环会带来很大的麻烦。因为 for...in 循环循环访问所有可枚举的属性,意味着如果向数组的原型中添加任何其他属性,这些属性也会出现在循环中。这就是为何在循环访问数组时,不建议使用 for...in 循环。

注意: forEach 循环 是另一种形式的 JavaScript 循环。但是,forEach() 实际上是数组方法,因此只能用在数组中。也无法停止或退出 forEach 循环。如果希望你的循环中出现这种行为,则需要使用基本的 for 循环。

for...of 循环

for...of 循环用于循环访问任何可迭代的数据类型。


const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
 console.log(digit);
}
登录后复制

可以随时停止或退出 for...of 循环。


const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
 if (digit % 2 === 0) {
  continue;
 }
 console.log(digit); //1,3,5,7,9
}
登录后复制

不用担心向对象中添加新的属性。for...of 循环将只循环访问对象中的值。

相关推荐:

实例分享PHP迭代器接口Iterator用法分析

调整JavaScript抽象的迭代方案

JavaScript数组的5种迭代方法实例详解


以上是ES6可迭代协议和迭代器协议详解的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

C++中的众数函数详解 C++中的众数函数详解 Nov 18, 2023 pm 03:08 PM

C++中的众数函数详解在统计学中,众数指的是一组数据中出现次数最多的数值。在C++语言中,我们可以通过编写一个众数函数来找到任意一组数据中的众数。众数函数的实现可以采用多种不同的方法,下面将详细介绍其中两种常用的方法。第一种方法是使用哈希表来统计每个数字出现的次数。首先,我们需要定义一个哈希表,将每个数字作为键,出现次数作为值。然后,对于给定的数据集,我们遍

Win11管理员权限获取详解 Win11管理员权限获取详解 Mar 08, 2024 pm 03:06 PM

Windows操作系统是全球最流行的操作系统之一,其新版本Win11备受瞩目。在Win11系统中,管理员权限的获取是一个重要的操作,管理员权限可以让用户对系统进行更多的操作和设置。本文将详细介绍在Win11系统中如何获取管理员权限,以及如何有效地管理权限。在Win11系统中,管理员权限分为本地管理员和域管理员两种。本地管理员是指具有对本地计算机的完全管理权限

Oracle SQL中的除法运算详解 Oracle SQL中的除法运算详解 Mar 10, 2024 am 09:51 AM

OracleSQL中的除法运算详解在OracleSQL中,除法运算是一种常见且重要的数学运算操作,用于计算两个数相除的结果。除法在数据库查询中经常用到,因此了解OracleSQL中的除法运算及其用法是数据库开发人员必备的技能之一。本文将详细讨论OracleSQL中除法运算的相关知识,并提供具体的代码示例供读者参考。一、OracleSQL中的除法运算

C++中的取余函数详解 C++中的取余函数详解 Nov 18, 2023 pm 02:41 PM

C++中的取余函数详解在C++中,取余运算符(%)用于计算两个数相除的余数。它是一种二元运算符,其操作数可以是任何整数类型(包括char、short、int、long等),也可以是浮点数类型(如float、double)。取余运算符返回的结果与被除数的符号相同。例如,对于整数的取余运算,我们可以使用以下代码来实现:inta=10;intb=3;

PHP模运算符的作用及用法详解 PHP模运算符的作用及用法详解 Mar 19, 2024 pm 04:33 PM

PHP中的模运算符(%)是用来获取两个数值相除的余数的。在本文中,我们将详细讨论模运算符的作用及用法,并提供具体的代码示例来帮助读者更好地理解。1.模运算符的作用在数学中,当我们将一个整数除以另一个整数时,会得到一个商和一个余数。例如,当我们将10除以3时,商为3,余数为1。模运算符就是用来获取这个余数的。2.模运算符的用法在PHP中,使用%符号来表示模

linux系统调用system()函数详解 linux系统调用system()函数详解 Feb 22, 2024 pm 08:21 PM

Linux系统调用system()函数详解系统调用是Linux操作系统中非常重要的一部分,它提供了一种与系统内核进行交互的方式。其中,system()函数是一个常用的系统调用函数之一。本文将详细介绍system()函数的使用方法,并提供相应的代码示例。系统调用的基本概念系统调用是用户程序与操作系统内核交互的一种方式。用户程序通过调用系统调用函数来请求操作系统

Linux的curl命令详解 Linux的curl命令详解 Feb 21, 2024 pm 10:33 PM

Linux的curl命令详解摘要:curl是一种强大的命令行工具,用于与服务器进行数据通信。本文将介绍curl命令的基本用法,并提供实际的代码示例,帮助读者更好地理解和应用该命令。一、curl是什么?curl是一个命令行工具,用于发送和接收各种网络请求。它支持多种协议,如HTTP、FTP、TELNET等,并提供了丰富的功能,如文件上传、文件下载、数据传输、代

详细解析C语言学习路线 详细解析C语言学习路线 Feb 18, 2024 am 10:38 AM

C语言作为一门广泛应用在软件开发领域的编程语言,是很多程序员初学者的首选。学习C语言不仅可以帮助我们建立编程的基础知识,还可以提升我们解决问题和思考的能力。本文将详细介绍一条C语言学习的路线图,帮助初学者更好地规划自己的学习进程。1.学习基本语法在开始学习C语言之前,我们首先需要了解C语言的基本语法规则。这包括变量和数据类型、运算符、控制语句(如if语句、

See all articles