ES6发电机和迭代器:开发人员指南
ES6为JavaScript语言引入了许多新特性。其中两个特性,生成器和迭代器,极大地改变了我们在更复杂的前端代码中编写特定函数的方式。
虽然它们可以很好地协同工作,但它们实际的功能可能有点令人困惑,所以让我们来仔细研究一下。
关键要点
- ES6提供了一种更简洁的for循环编写方式,提供了一种更类似Python的方式来直接与数据集中的元素交互,使代码更易于阅读和编写。
- ES6中的生成器是记住每次调用之间状态的函数。它们每次被调用时都可以生成序列中的下一个值,有效地创建自定义迭代。
- 生成器函数中的“yield”关键字类似于“return”,但它保持函数的状态,允许它在下一次调用时从中断处继续执行。
- 虽然Node和现代浏览器支持ES6特性,但旧版浏览器可能需要Babel等转译器将ES6代码转换为ECMAScript 5代码。
迭代器
迭代是编程中常见的做法,通常用于循环遍历一组值,转换每个值,或以某种方式使用或保存它以备后用。
在JavaScript中,我们一直都有这样的for循环:
for (var i = 0; i < foo.length; i++) { // 对i执行某些操作 }
但ES6给了我们另一种选择:
for (const i of foo) { // 对i执行某些操作 }
这可以说是更简洁、更容易使用,让我想起了Python和Ruby等语言。但是,关于这种新型迭代,还有一点非常重要需要注意:它允许您直接与数据集的元素交互。
假设我们想找出数组中的每个数字是否为素数。我们可以通过创建一个执行此操作的函数来做到这一点。它可能看起来像这样:
function isPrime(number) { if (number <= 1) { return false; } else if (number === 2) { return true; } for (var i = 2; i < number; i++) { if (number % i === 0) { return false; break; } } return true; }
不是世界上最好的,但它有效。下一步是循环遍历我们的数字列表,并使用我们闪亮的新函数检查每个数字是否为素数。这很简单:
var possiblePrimes = [73, 6, 90, 19, 15]; var confirmedPrimes = []; for (var i = 0; i < possiblePrimes.length; i++) { if (isPrime(possiblePrimes[i])) { confirmedPrimes.push(possiblePrimes[i]); } } // confirmedPrimes现在是[73, 19]
同样,它有效,但它很笨拙,这种笨拙很大程度上取决于JavaScript处理for循环的方式。但是,有了ES6,我们就在新的迭代器中得到了一个几乎类似Python的选项。因此,前面的for循环可以这样编写:
const possiblePrimes = [73, 6, 90, 19, 15]; const confirmedPrimes = []; for (const i of possiblePrimes){ if ( isPrime(i) ){ confirmedPrimes.push(i); } } // confirmedPrimes现在是[73, 19]
这要干净得多,但最引人注目的是for循环。变量i现在代表名为possiblePrimes的数组中的实际项。因此,我们不再需要按索引调用它了。这意味着我们不必在循环中调用possiblePrimes[i],而只需调用i即可。
在幕后,这种迭代利用了ES6闪亮的新Symbol.iterator()方法。这个方法负责描述迭代,并且在被调用时,返回一个JavaScript对象,其中包含循环中的下一个值和一个done键,该键根据循环是否完成而为true或false。
如果您对这种细节感兴趣,您可以阅读Jake Archibald撰写的这篇精彩博文《Iterators gonna iterate》。当我们深入探讨本文的另一部分:生成器时,它也会让您很好地了解幕后发生了什么。
生成器
生成器(也称为“迭代器工厂”)是一种新型的JavaScript函数,用于创建特定的迭代。它们为您提供了特殊、自定义的循环遍历内容的方式。
好的,那么这一切意味着什么?让我们来看一个例子。假设我们想要一个函数,每次调用它时都会给我们下一个素数:
for (var i = 0; i < foo.length; i++) { // 对i执行某些操作 }
如果您习惯使用JavaScript,其中一些内容看起来有点像巫术,但实际上它并不太糟糕。我们在关键字function之后有那个奇怪的星号,但这只是告诉JavaScript我们正在定义一个生成器。
另一个奇怪的部分是yield关键字。这实际上是生成器在您调用它时吐出的内容。它大致相当于return,但它保留了函数的状态,而不是在每次调用它时都重新运行所有内容。它在运行时“记住”它的位置,因此下次您调用它时,它会从中断处继续执行。
这意味着我们可以这样做:
for (const i of foo) { // 对i执行某些操作 }
然后,每当我们想要获得——你猜对了——下一个素数时,都可以调用nextPrime:
function isPrime(number) { if (number <= 1) { return false; } else if (number === 2) { return true; } for (var i = 2; i < number; i++) { if (number % i === 0) { return false; break; } } return true; }
您也可以只调用nextPrime.next(),这在您的生成器不是无限的情况下很有用,因为它返回一个这样的对象:
var possiblePrimes = [73, 6, 90, 19, 15]; var confirmedPrimes = []; for (var i = 0; i < possiblePrimes.length; i++) { if (isPrime(possiblePrimes[i])) { confirmedPrimes.push(possiblePrimes[i]); } } // confirmedPrimes现在是[73, 19]
在这里,done键告诉您函数是否已完成其任务。在我们的例子中,我们的函数永远不会结束,理论上可以为我们提供所有直到无穷大的素数(如果我们有那么多的计算机内存的话)。
很酷,那么我现在可以使用生成器和迭代器了吗?
尽管ECMAScript 2015已经完成,并且已经存在多年了,但其特性(特别是生成器)的浏览器支持远未完善。如果您真的想使用这些和其他现代特性,您可以查看Babel和Traceur等转译器,它们会将您的ECMAScript 2015代码转换为等效的(如果可能)ECMAScript 5代码。
还有许多在线编辑器支持ECMAScript 2015,或者专门关注它,特别是Facebook的Regenerator和JS Bin。如果您只是想玩玩并了解JavaScript现在如何编写,那么这些值得一看。
结论
生成器和迭代器为我们处理JavaScript问题的方法提供了相当多的新灵活性。迭代器允许我们以更类似Python的方式编写for循环,这意味着我们的代码看起来更简洁,更容易阅读。
生成器函数使我们能够编写记住上次看到它们的位置的函数,并且可以从中断处继续执行。它们在实际记住的内容方面也可以是无限的,这在某些情况下非常方便。
对这些生成器和迭代器的支持很好。它们在Node和所有现代浏览器中都受支持,Internet Explorer除外。如果您需要支持旧版浏览器,最好的办法是使用Babel等转译器。
关于ECMAScript 2015生成器和迭代器的常见问题解答 (FAQ)
ECMAScript 2015中的迭代器和生成器有什么区别?
迭代器和生成器都是ECMAScript 2015的特性,用于处理数据流。迭代器是一个对象,允许程序员遍历集合中的所有元素。它有一个next()方法,返回序列中的下一个项目。另一方面,生成器是一个可以中途停止然后从停止处继续的函数。换句话说,生成器看起来像一个函数,但它的行为像一个迭代器。
如何在ECMAScript 2015中使用yield关键字?
yield关键字用于ECMAScript 2015暂停和恢复生成器函数(function*或旧版生成器函数)。yield可以从生成器函数返回一个值。这个返回值通常是一个具有两个属性的对象:value和done。value属性是计算yield表达式的结果,done是一个布尔值,指示生成器是否已生成其最后一个值。
ECMAScript 2015中next()方法的目的是什么?
next()方法是ECMAScript 2015中迭代器协议的关键部分。它返回一个具有两个属性的对象:value和done。value属性是迭代序列中的下一个值,done是一个布尔值,指示迭代是否完成。如果done为true,则迭代器已超出迭代序列的末尾。
如何在ECMAScript 2015中使用生成器进行异步编程?
ECMAScript 2015中的生成器可用于简化异步编程。它们可用于阻止执行以等待异步操作完成,而不会阻塞整个程序。这可以使异步代码看起来和行为更像同步代码,这更容易理解和推理。
ECMAScript 2015中for…of循环和for…in循环有什么区别?
ECMAScript 2015中的for…of循环用于循环遍历可迭代对象,例如数组、字符串、映射、集合等等。它使用语句调用自定义迭代钩子,这些语句将为每个不同属性的值执行。另一方面,for…in循环用于循环遍历对象的属性。它返回正在迭代的对象的键列表。
如何在ECMAScript 2015中创建自定义迭代器?
在ECMAScript 2015中,您可以通过定义一个具有next()方法的对象来创建自定义迭代器。此方法应返回一个具有两个属性的对象:value和done。value属性是迭代序列中的下一个值,done是一个布尔值,指示迭代是否完成。
Symbol.iterator在ECMAScript 2015中的作用是什么?
Symbol.iterator是ECMAScript 2015中一个特殊的内置符号。它用于指定对象的默认迭代器。当需要迭代一个对象时(例如在for…of循环的开头),它的@@iterator方法将不带任何参数被调用,并且返回的迭代器将用于获取要迭代的值。
你能提供ECMAScript 2015中生成器函数的示例吗?
当然,这是ECMAScript 2015中生成器函数的一个简单示例:
for (var i = 0; i < foo.length; i++) { // 对i执行某些操作 }
在这个例子中,idMaker函数是一个生成器,它产生一个数字序列。
如何在ECMAScript 2015中使用throw()方法和生成器?
ECMAScript 2015中的throw()方法可用于生成器,以恢复生成器函数的执行并从yield表达式抛出错误。throw()方法可用于处理生成器函数执行期间发生的错误。
done属性在ECMAScript 2015迭代器中的意义是什么?
done属性是一个布尔值,由ECMAScript 2015中的迭代器返回。它指示迭代器是否还有更多值要返回。如果done为true,则迭代器已超出迭代序列的末尾。如果done为false,则迭代器仍然可以生成更多值。
以上是ES6发电机和迭代器:开发人员指南的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...
