Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1128529 of Generator推导式

  • 版本网址缩略名: Web/JavaScript/Reference/Operators/Generator_comprehensions
  • 版本标题: Generator推导式
  • 版本 id: 1128529
  • 创建于:
  • 创建者: Jiasm
  • 是否是当前版本?
  • 评论 错别字-.-

修订内容

{{jsSidebar("Operators")}} {{es7}}

The generator comprehension syntax is a JavaScript expression which allows you to quickly assemble a new generator function based on an existing iterable object. Comprehensions exist in many programming languages and the upcoming ECMAScript 7 standard defines array comprehensions for JavaScript.

See below for differences to the old generator expression syntax in SpiderMonkey, based on proposals for ECMAScript 4.

语法

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

描述

Inside generator comprehensions, these two kinds of components are allowed:

  • {{jsxref("Statements/for...of", "for...of")}} and
  • {{jsxref("Statements/if...else", "if")}}

The for-of iteration is always the first component. Multiple for-of iterations or if statements are allowed.

示例

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"

Generator comprehensions with if statement

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 comprehensions compared to generator function

An easy way to understand generator comprehension syntax, is to compare it with the generator function.

Example 1: Simple generator.

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 ]

Example 2: Using if in generator.

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 ]

规范

规范 状态 说明
Proposed for ECMAScript 7 No draft available yet Was initially in the ECMAScript 6 draft, but got removed in revision 27 (August 2014). Please see older revisions of ES 6 for specification semantics. An updated version will be back in a new  ES 7 draft.

浏览器兼容性

{{CompatibilityTable}}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{CompatNo}} {{ CompatGeckoDesktop("30") }} {{CompatNo}} {{CompatNo}} {{CompatNo}}
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{CompatNo}} {{CompatNo}} {{ CompatGeckoMobile("30") }} {{CompatNo}} {{CompatNo}} {{CompatNo}}

SpiderMonkey-specific implementation notes

  • {{jsxref("Statements/let", "let")}} as an identifier is not supported as let is currently only available to JS version 1.7 and XUL scripts tags.
  • Destructuring in comprehensions is not supported yet ({{bug(980828)}}).

Differences to the older JS1.7/JS1.8 comprehensions

  • ES7 comprehensions create one scope per "for" node instead of the comprehension as a whole.
    • Old: [...(()=>x for (x of [0, 1, 2]))][1]() // 2
    • New: [...(for (x of [0, 1, 2]) ()=>x)][1]() // 1, each iteration creates a fresh binding for x.
  • ES7 comprehensions start with "for" instead of the assignment expression.
    • Old: (i * 2 for (i of numbers))
    • New: (for (i of numbers) i * 2)
  • ES7 comprehensions can have multiple if and for components.
  • ES7 comprehensions only work with {{jsxref("Statements/for...of", "for...of")}} and not with {{jsxref("Statements/for...in", "for...in")}} iterations.

相关链接

  • {{jsxref("Statements/for...of", "for...of")}}
  • {{jsxref("Operators/Array_comprehensions", "Array comprehensions")}}

修订版来源

<div>{{jsSidebar("Operators")}} {{es7}}</div>

<p>The <strong>generator comprehension</strong> syntax is a JavaScript expression which allows you to quickly assemble a new generator function based on an existing iterable object. Comprehensions exist in many programming languages and the upcoming ECMAScript 7 standard defines array comprehensions for JavaScript.</p>

<p>See <a href="#Differences_to_the_older_JS1.7.2FJS1.8_comprehensions">below</a> for differences to the old generator expression syntax in SpiderMonkey, based on proposals for ECMAScript 4.</p>

<h2 id="语法">语法</h2>

<pre class="syntaxbox">
(for (x of iterable) x)
(for (x of iterable) if (condition) x)
(for (x of iterable) for (y of iterable) x + y)
</pre>

<h2 id="描述">描述</h2>

<p>Inside generator comprehensions, these two kinds of components are allowed:</p>

<ul>
 <li>{{jsxref("Statements/for...of", "for...of")}} and</li>
 <li>{{jsxref("Statements/if...else", "if")}}</li>
</ul>

<p>The <code>for-of</code> iteration is always the first component. Multiple <code>for-of</code> iterations or if statements are allowed.</p>

<h2 id="示例">示例</h2>

<h3 id="Simple_generator_comprehensions">Simple generator comprehensions</h3>

<pre class="brush: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"
</pre>

<h3 id="Generator_comprehensions_with_if_statement">Generator comprehensions with if statement</h3>

<pre class="brush: js">
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
</pre>

<h3 id="Generator_comprehensions_compared_to_generator_function">Generator comprehensions compared to generator function</h3>

<p>An easy way to understand generator comprehension syntax, is to compare it with the generator function.</p>

<p>Example 1: Simple generator.</p>

<pre class="brush: js">
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 ]
</pre>

<p>Example 2: Using <code>if</code> in generator.</p>

<pre class="brush: js">
var numbers = [ 1, 2, 3 ];

// Generator function
(function*() {
  for (let i of numbers) {
    if (i &lt; 3) {
      yield i * 1;
    }
  }
})()

// Generator comprehension
(for (i of numbers) if (i &lt; 3) i);

// Result: both return a generator which yields [ 1, 2 ]</pre>

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">规范</th>
   <th scope="col">状态</th>
   <th scope="col">说明</th>
  </tr>
  <tr>
   <td>Proposed for ECMAScript 7</td>
   <td>No draft available yet</td>
   <td>Was initially in the ECMAScript 6 draft, but got removed in revision 27 (August 2014). Please see older revisions of ES 6 for specification semantics. An updated version will be back in a new&nbsp; ES 7 draft.</td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<p>{{CompatibilityTable}}</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>{{CompatNo}}</td>
   <td>{{ CompatGeckoDesktop("30") }}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</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>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{ CompatGeckoMobile("30") }}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
 </tbody>
</table>
</div>

<h3 id="SpiderMonkey-specific_implementation_notes">SpiderMonkey-specific implementation notes</h3>

<ul>
 <li>{{jsxref("Statements/let", "let")}} as an identifier is not supported as <code>let</code> is currently only available to JS version 1.7 and XUL scripts tags.</li>
 <li>Destructuring in comprehensions is not supported yet ({{bug(980828)}}).</li>
</ul>

<h3 id="Differences_to_the_older_JS1.7JS1.8_comprehensions">Differences to the older JS1.7/JS1.8 comprehensions</h3>

<ul>
 <li>ES7 comprehensions create one scope per "for" node instead of the comprehension as a whole.
  <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, each iteration creates a fresh binding for x. </code></li>
  </ul>
 </li>
 <li>ES7 comprehensions start with "for" instead of the assignment expression.
  <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>ES7 comprehensions can have multiple <code>if</code> and <code>for</code> components.</li>
 <li>ES7 comprehensions only work with <code>{{jsxref("Statements/for...of", "for...of")}}</code> and not with <code>{{jsxref("Statements/for...in", "for...in")}}</code> iterations.</li>
</ul>

<h2 id="相关链接">相关链接</h2>

<ul>
 <li>{{jsxref("Statements/for...of", "for...of")}}</li>
 <li>{{jsxref("Operators/Array_comprehensions", "Array comprehensions")}}</li>
</ul>
恢复到这个版本