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的旧版本。
浏览器兼容性
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | No support | 30 (30) | No support | No support | No support |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | No support | No support | 30.0 (30) | No support | No support | No 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”节点创建一个范围,而不是作为一个整体理解。