在线文档教程

Generator comprehensions

生成器解析

非标。不使用!

生成器解析是非标准的,它不太可能被添加到ECMAScript中,对于面向未来的用法,请考虑使用生成器。

生成器解析语法是一个JavaScript表达式,它允许您快速组装基于现有迭代对象上一个新的生成功能。理解存在于许多编程语言中。

根据ECMAScript 4的提议,请参阅下面的SpiderMonkey中的旧生成器表达式语法的差异。

句法

(for (x of iterable) x) (for (x of iterable) if (condition) x) (for (x of iterable) for (y of iterable) x + y)

描述

在生成器解释中,允许这两种组件:

  • for...of and

for-of迭代总是第一个组件。多重for-of迭代或if语句被允许。

数组理解的一个显着缺点是它们导致整个新数组在内存中被构造。当理解的输入本身就是一个小数组时,所涉及的开销不大 - 但是当输入是一个大数组或者一个昂贵的(或者确实是无限的)生成器时,创建一个新数组可能会产生问题。

生成器启用序列的延迟计算,并根据需要按需计算项目。发生器理解在语法上几乎与数组理解相同 - 它们使用圆括号而不是大括号 - 但不是构建数组,而是创建一个可以执行延迟的生成器。您可以将它们视为创建生成器的简短语法。

假设我们有一个it遍历大整数序列的迭代器。我们想要创建一个迭代器来迭代他们的doubles。数组理解将在内存中创建一个包含doubled值的完整数组:

var doubles = [for (i in it) i * 2];

另一方面,生成器理解会创建一个新的迭代器,在需要时可根据需要创建双倍的值:

var it2 = (for (i in it) i * 2 console.log(it2.next() // The first value from it, doubled console.log(it2.next() // The second value from it, doubled

当生成器理解被用作函数的参数时,用于函数调用的括号意味着可以省略外部圆括号:

var result = doSomething(for (i in it) i * 2

这两个例子之间的显着差异在于,通过使用生成器理解,您只需循环遍历'obj'结构一次,全部,而不是一次理解数组,再循环遍历它。

示例

Simple generator comprehensions

(for (i of [1, 2, 3]) i * i // generator function which yields 1, 4, and 9 [...(for (i of [1, 2, 3]) i * i )]; // [1, 4, 9] var abc = ['A', 'B', 'C']; (for (letters of abc) letters.toLowerCase() // generator function which yields "a", "b", and "c"

使用if语句的生成器解析

var years = [1954, 1974, 1990, 2006, 2010, 2014]; (for (year of years) if (year > 2000) year // generator function which yields 2006, 2010, and 2014 (for (year of years) if (year > 2000) if (year < 2010) year // generator function which yields 2006, the same as below: (for (year of years) if (year > 2000 && year < 2010) year // generator function which yields 2006

与生成器解析相比较的生成器函数

理解生成器理解语法的一种简单方法是将其与生成器函数进行比较。

例1:简单的生成器。

var numbers = [1, 2, 3]; // Generator function (function*() { for (let i of numbers) { yield i * i; } })( // Generator comprehension (for (i of numbers) i * i // Result: both return a generator which yields [1, 4, 9]

示例2:使用if生成器。

var numbers = [1, 2, 3]; // Generator function (function*() { for (let i of numbers) { if (i < 3) { yield i * 1; } } })( // Generator comprehension (for (i of numbers) if (i < 3) i // Result: both return a generator which yields [1, 2]

规范

生成器解析最初在ECMAScript 2015草案中,但在修订版27(2014年8月)中删除。有关规范语义,请参阅ES2015的旧版本。

浏览器兼容性

FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic supportNo support30 (30)No supportNo supportNo support

FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic supportNo supportNo support30.0 (30)No supportNo supportNo support

SpiderMonkey特定的实现说明

  • let因为let目前只支持JS版本1.7和XUL脚本标记,所以不支持标识符。

与较老的JS1.7/JS1.8的解析不同

从Gecko 46中删除JS1.7/JS1.8的解析(bug 1220564)。

旧的解析语法(不再使用!):

(X for (Y in Z)) (X for each (Y in Z)) (X for (Y of Z))

区别:

  • ES7理解为每个“for”节点创建一个范围,而不是作为一个整体理解。