uTools-Manuals/docs/javascript/Reference/Operators/Generator_comprehensions.html
2019-04-21 11:50:48 +08:00

167 lines
8.2 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<article id="wikiArticle">
<div class="warning"><strong>非标准的。不要使用!</strong><br/>
generator推导式是非标准的而且它不太可能会被添加到ECMAScript。考虑到将来请使用 <a href="Reference/Statements/function*" title="function* 这种声明方式(function关键字后跟一个星号会定义一个生成器函数 (generator function),它返回一个  Generator  对象。">generator</a>
<p> </p>
</div>
<p></p><p></p>
<p>生成器推导语法是一种JavaScript表达式它允许您基于现有的可迭代对象快速组合新的生成器函数。</p>
<p>许多编程语言中都存在推导。</p>
<p>看下面原来Generator推导式语法在SpiderMonkey的不同之处它是基于对ECMAScript4的提议。</p>
<h2 id="语法">语法</h2>
<pre><code class="language-javascript">(for (x of iterable) x)
(for (x of iterable) if (condition) x)
(for (x of iterable) for (y of iterable) x + y)
</code></pre>
<h2 id="描述">描述</h2>
<p>在Generator推导式中这两种构成方式都是允许的</p>
<ul>
<li><a href="Reference/Statements/for...of" title="for...of语句在可迭代对象包括 ArrayMapSetStringTypedArrayarguments 对象等等上创建一个迭代循环调用自定义迭代钩子并为每个不同属性的值执行语句"><code>for...of</code></a> </li>
<li><a href="Reference/Statements/if...else" title="当指定条件为真if 语句会执行一段语句。如果条件为假,则执行另一段语句。"><code>if</code></a></li>
</ul>
<p>for-of迭代器是构成的第一个部分。当由多重部分构成时后面for-of和if构成方式都是被允许的。</p>
<h2 id="示例">示例</h2>
<h3 id="单个构成部分的_generator推导式">单个构成部分的 generator推导式</h3>
<pre><code class="language-js">(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"
</code></pre>
<h3 id="有if伴随的多重构成的gennerator推导式">有if伴随的多重构成的gennerator推导式</h3>
<pre><code class="language-javascript">var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
(for (year of years) if (year &gt; 2000) year);
// generator function which yields 2006, 2010, and 2014
(for (year of years) if (year &gt; 2000) if(year &lt; 2010) year);
// generator function which yields 2006, the same as below:
(for (year of years) if (year &gt; 2000 &amp;&amp; year &lt; 2010) year);
// generator function which yields 2006
</code></pre>
<h3 id="Generator推导式与Generator函数对比">Generator推导式与Generator函数对比</h3>
<p>用一种简单的方式来理解generator推导式的语法并与generator函数来做个比较。</p>
<p>Example 1: 仅是 generator.</p>
<pre><code class="language-javascript">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 ]
</code></pre>
<p>Example 2: 在 generator 中用if.</p>
<pre><code class="language-javascript">var numbers = [ 1, 2, 3 ];
// Generator 函数
(function*() {
for (let i of numbers) {
if (i &lt; 3) {
yield i * 1;
}
}
})()
// Generator 推导式
(for (i of numbers) if (i &lt; 3) i);
// 结果: 两者都得到 yields [ 1, 2 ]</code></pre>
<h2 id="规范">规范</h2>
<p>Generator推导式是最初在ECMAScript 2015中进行拟稿,但是在14年8月27号修订中被移除了。 请参阅较旧版本的ES2015规范语义.</p>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<p></p><div class="blockIndicator warning"><strong><a class="external" href="https://github.com/mdn/browser-compat-data" rel="noopener">We're converting our compatibility data into a machine-readable JSON format</a></strong>.
This compatibility table still uses the old format,
because we haven't yet converted the data it contains.
<strong><a class="new" href="/zh-CN/docs/MDN/Contribute/Structures/Compatibility_tables" rel="nofollow">Find out how you can help!</a></strong></div>
<div class="htab">
<a id="AutoCompatibilityTable" name="AutoCompatibilityTable"></a>
<ul>
<li class="selected"><a>Desktop</a></li>
<li><a>Mobile</a></li>
</ul>
</div><p></p>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Chrome</th>
<th>Firefox (Gecko)</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td>Basic support</td>
<td><span style="color: #f00;">未实现</span></td>
<td><a href="/en-US/Firefox/Releases/30" title="Released on 2014-06-10.">30</a> (30)</td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Android</th>
<th>Chrome for Android</th>
<th>Firefox Mobile (Gecko)</th>
<th>IE Mobile</th>
<th>Opera Mobile</th>
<th>Safari Mobile</th>
</tr>
<tr>
<td>Basic support</td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
<td>30.0 (30)</td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
</tr>
</tbody>
</table>
</div>
<h3 id="SpiderMonkey的具体实现笔记">SpiderMonkey的具体实现笔记</h3>
<ul>
<li><a href="Reference/Statements/let" title="let允许你声明一个作用域被限制在块级中的变量、语句或者表达式。与var关键字不同的是var声明的变量只能是全局或者整个函数块的。"><code>let</code></a> 作为标识符因为let当前仅可用于JS版本1.7和XUL脚本标记.</li>
<li>目前还不支持解构 (<a class="external" href="https://bugzilla.mozilla.org/show_bug.cgi?id=980828" rel="noopener" title="Generator and array comprehensions should support destructuring binding">bug 980828</a>).</li>
</ul>
<h3 id="与旧的JS1.7_JS1.8理解的区别">与旧的JS1.7 / JS1.8理解的区别</h3>
<ul>
<li>ES2016 的解析为每个“for”节点创建一个范围而不是作为一个整体的理解。
<ul>
<li>Old: <code>[...(()=&gt;x for (x of [0, 1, 2]))][1]() // 2</code></li>
<li>New: <code>[...(for (x of [0, 1, 2]) ()=&gt;x)][1]() // 1, 每个迭代都会创建一个新的x的绑定事件。</code></li>
</ul>
</li>
<li> ES2016的解析以“for”而不是赋值表达式开头。
<ul>
<li>Old: <code>(i * 2 for (i of numbers))</code></li>
<li>New: <code>(for (i of numbers) <code>i * 2</code>)</code></li>
</ul>
</li>
<li>ES2016 解析可以有多个if和for组件。</li>
<li>ES2016 解析仅这种方式工作<code><a href="Reference/Statements/for...of" title="for...of语句在可迭代对象包括 ArrayMapSetStringTypedArrayarguments 对象等等上创建一个迭代循环调用自定义迭代钩子并为每个不同属性的值执行语句"><code>for...of</code></a></code> 而不是<code><a href="Reference/Statements/for...in" title="for...in语句以任意顺序遍历一个对象的可枚举属性。对于每个不同的属性语句都会被执行。"><code>for...in</code></a></code> 的方式迭代。</li>
</ul>
<h2 id="相关链接">相关链接</h2>
<ul>
<li><a href="Reference/Statements/for...of" title="for...of语句在可迭代对象包括 ArrayMapSetStringTypedArrayarguments 对象等等上创建一个迭代循环调用自定义迭代钩子并为每个不同属性的值执行语句"><code>for...of</code></a></li>
<li><a href="Reference/Operators/Array_comprehensions" title="数组推导式是一种 JavaScript 表达式语法,使用它,你可以在一个原有数组的基础上快速的构造出一个新的数组。但是它已经从标准和火狐中移除。不要用它!"><code>Array comprehensions</code></a></li>
</ul>
</article>