Python 拥有许多强大的实用函数,例如 range
、enumerate
、zip
等,这些函数基于可迭代对象和迭代器协议构建。结合生成器函数,这些协议自 2016 年左右起就在所有 Evergreen 浏览器和 Node.js 中可用,但在我看来,它们的使用率却低得令人吃惊。在这篇文章中,我将使用 TypeScript 实现其中一些辅助函数,希望能改变这种现状。
迭代器、可迭代对象和生成器函数
迭代器协议
迭代器协议是一种生成值序列的标准方法。要使一个对象成为迭代器,它必须通过实现 next
方法来遵守迭代器协议,例如:
const iterator = { i: 0, next() { return { done: false, value: this.i++ }; } };
然后,我们可以重复调用 next
方法来获取值:
console.log(iterator.next().value); // → 0 console.log(iterator.next().value); // → 1 console.log(iterator.next().value); // → 2 console.log(iterator.next().value); // → 3 console.log(iterator.next().value); // → 4
next
方法应该返回一个对象,该对象包含一个 value
属性(包含实际值)和一个 done
属性(指定迭代器是否已耗尽,即是否无法再生成值)。根据 MDN 的说法,这两个属性都不是严格必需的,如果两者都缺失,则返回值被视为 { done: false, value: undefined }
。
可迭代对象协议
可迭代对象协议允许对象定义其自身的迭代行为。要遵守可迭代对象协议,对象必须使用 Symbol.iterator
键定义一个方法,该方法返回一个迭代器。许多内置对象(如 Array
、TypedArray
、Set
和 Map
)都实现了此协议,因此可以使用 for...of
循环对其进行迭代。
例如,对于数组,values
方法被指定为数组的 Symbol.iterator
方法:
console.log(Array.prototype.values === Array.prototype[Symbol.iterator]); // → true
我们可以结合迭代器和可迭代对象协议来创建一个可迭代的迭代器,如下所示:
const iterable = { i: 0, [Symbol.iterator]() { const iterable = this; return { next() { return { done: false, value: iterable.i++ }; } }; } };
这两个协议的名称不幸地非常相似,至今仍然让我感到困惑。
正如您可能猜到的那样,我们的迭代器和可迭代对象示例是无限的,这意味着它们可以永远生成值。这是一个非常强大的特性,但也容易成为一个陷阱。例如,如果我们要在一个 for...of
循环中使用可迭代对象,则循环将永远持续下去;或者用作 Array.from
的参数,JS 最终会抛出一个 RangeError
,因为数组会变得太大:
// 将无限循环: for (const value of iterable) { console.log(value); } // 将抛出 RangeError const arr = Array.from(iterable);
迭代器和可迭代对象甚至可以无限的原因是它们是惰性求值的,即只有在使用时才会生成值。
生成器函数
虽然迭代器和可迭代对象是宝贵的工具,但编写起来有点麻烦。作为替代方案,引入了生成器函数。
生成器函数使用 function*
(或 function *
,星号可以在 function
关键字和函数名称之间任意位置)指定,允许我们中断函数的执行,使用 yield
关键字返回值,并在稍后继续中断的地方继续执行,同时保持其内部状态:
const iterator = { i: 0, next() { return { done: false, value: this.i++ }; } };
Python 实用程序
如引言中所述,Python 有一些非常有用的内置实用程序,它们基于上述协议。JavaScript 最近也为迭代器增加了一些辅助方法,例如 .drop()
和 .filter()
,但(也许还没有)拥有 Python 中一些更有趣的实用程序。
让我们动手实践!
现在理论部分已经结束,让我们开始实现一些 Python 函数吧!
注意:此处显示的这些实现都不应按原样用于生产环境。 它们缺乏错误处理和边界条件检查。
enumerate(iterable [,start])
Python 中的 enumerate
为输入序列或可迭代对象中的每个项目返回一系列元组,其中第一个位置包含计数,第二个位置包含项目:
console.log(iterator.next().value); // → 0 console.log(iterator.next().value); // → 1 console.log(iterator.next().value); // → 2 console.log(iterator.next().value); // → 3 console.log(iterator.next().value); // → 4
enumerate
还接受一个可选的 start
参数,指示计数器应从何处开始:
console.log(Array.prototype.values === Array.prototype[Symbol.iterator]); // → true
让我们使用生成器函数在 TypeScript 中实现它。我们可以使用 python 文档中概述的实现作为指导
const iterable = { i: 0, [Symbol.iterator]() { const iterable = this; return { next() { return { done: false, value: iterable.i++ }; } }; } };
由于 JavaScript 中的字符串实现了可迭代对象协议,我们可以简单地将字符串传递给我们的 enumerate
函数并像这样调用它:
// 将无限循环: for (const value of iterable) { console.log(value); } // 将抛出 RangeError const arr = Array.from(iterable);
repeat(elem [,n])
repeat
是内置 itertools
库的一部分,它重复给定的输入 elem
n 次,如果未指定 n,则无限重复。我们再次可以将 python 文档中的实现作为起点。
function* sequence() { let i = 0; while (true) { yield i++; } } const seq = sequence(); console.log(seq.next().value); // → 0; console.log(seq.next().value); // → 1; console.log(seq.next().value); // → 2; // 将无限循环,从 3 开始 for (const value of seq) { console.log(value); }
(此处省略了 cycle
、range
函数的实现,因为篇幅过长,但其逻辑与原文相同,只是将代码用 TypeScript 重写)
结论
这是我的第一篇博客文章,我希望您觉得它有趣,并且也许您会在未来的项目中使用迭代器、可迭代对象和生成器。如果您有任何疑问或需要澄清,请留下评论,我很乐意提供更多信息。
需要注意的是,与使用计数器的原始 for
循环相比,性能相差甚远。这在许多情况下可能无关紧要,但在高性能场景中绝对很重要。当我将 PCM 数据绘制到画布上并使用迭代器和生成器时,发现帧丢失了,这让我很苦恼。事后看来这可能是显而易见的,但当时对我来说却并非如此 :D
干杯!
以上是Python 化 JavaScript的详细内容。更多信息请关注PHP中文网其他相关文章!

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。

要在有限的时间内最大化学习Python的效率,可以使用Python的datetime、time和schedule模块。1.datetime模块用于记录和规划学习时间。2.time模块帮助设置学习和休息时间。3.schedule模块自动化安排每周学习任务。

Python在游戏和GUI开发中表现出色。1)游戏开发使用Pygame,提供绘图、音频等功能,适合创建2D游戏。2)GUI开发可选择Tkinter或PyQt,Tkinter简单易用,PyQt功能丰富,适合专业开发。

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。 Python以简洁和强大的生态系统着称,C 则以高性能和底层控制能力闻名。

2小时内可以学会Python的基本编程概念和技能。1.学习变量和数据类型,2.掌握控制流(条件语句和循环),3.理解函数的定义和使用,4.通过简单示例和代码片段快速上手Python编程。

Python在web开发、数据科学、机器学习、自动化和脚本编写等领域有广泛应用。1)在web开发中,Django和Flask框架简化了开发过程。2)数据科学和机器学习领域,NumPy、Pandas、Scikit-learn和TensorFlow库提供了强大支持。3)自动化和脚本编写方面,Python适用于自动化测试和系统管理等任务。

两小时内可以学到Python的基础知识。1.学习变量和数据类型,2.掌握控制结构如if语句和循环,3.了解函数的定义和使用。这些将帮助你开始编写简单的Python程序。

如何在10小时内教计算机小白编程基础?如果你只有10个小时来教计算机小白一些编程知识,你会选择教些什么�...


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

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

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

Dreamweaver CS6
视觉化网页开发工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

Dreamweaver Mac版
视觉化网页开发工具