生成器推导语法是一种JavaScript表达式,它允许您基于现有的可迭代对象快速组合新的生成器函数。
许多编程语言中都存在推导。
看下面,原来Generator推导式语法在SpiderMonkey的不同之处,它是基于对ECMAScript4的提议。
语法
(for (x of iterable) x) (for (x of iterable) if (condition) x) (for (x of iterable) for (y of iterable) x + y)
描述
在Generator推导式中,这两种构成方式都是允许的:
for-of迭代器是构成的第一个部分。当由多重部分构成时,后面for-of和if构成方式都是被允许的。
示例
单个构成部分的 generator推导式:
(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伴随的多重构成的gennerator推导式:
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
Generator推导式与Generator函数对比
用一种简单的方式来理解generator推导式的语法并与generator函数来做个比较。
Example 1: 仅是 generator.
var numbers = [ 1, 2, 3 ]; // Generator 函数 (function*() { for (let i of numbers) { yield i * i; } })() // Generator 推导式 (for (i of numbers) i*i ); // 结果: 两者都得到 yields [ 1, 4, 9 ]
Example 2: 在 generator 中用if.
var numbers = [ 1, 2, 3 ]; // Generator 函数 (function*() { for (let i of numbers) { if (i < 3) { yield i * 1; } } })() // Generator 推导式 (for (i of numbers) if (i < 3) i); // 结果: 两者都得到 yields [ 1, 2 ]
规范
Generator推导式是最初在ECMAScript 2015中进行拟稿,但是在14年8月27号修订中被移除了。 请参阅较旧版本的ES2015规范语义.
浏览器兼容性
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 未实现 | 30 (30) | 未实现 | 未实现 | 未实现 |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | 未实现 | 未实现 | 30.0 (30) | 未实现 | 未实现 | 未实现 |
SpiderMonkey的具体实现笔记
let
作为标识符,因为let当前仅可用于JS版本1.7和XUL脚本标记.- 目前还不支持解构 (bug 980828).
与旧的JS1.7 / JS1.8理解的区别
- ES2016 的解析为每个“for”节点创建一个范围,而不是作为一个整体的理解。
- Old:
[...(()=>x for (x of [0, 1, 2]))][1]() // 2
- New:
[...(for (x of [0, 1, 2]) ()=>x)][1]() // 1, 每个迭代都会创建一个新的x的绑定事件。
- Old:
- ES2016的解析以“for”而不是赋值表达式开头。
- Old:
(i * 2 for (i of numbers))
- New:
(for (i of numbers)
i * 2
)
- Old:
- ES2016 解析可以有多个if和for组件。
- ES2016 解析仅这种方式工作
而不是for...of
的方式迭代。for...in