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

159 lines
14 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">
<p><strong>非标准。不要使用!</strong><br/>
数组推导是非标准的。以后应该用 <a href="Reference/Global_Objects/Array/map" title="map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。"><code>Array.prototype.map</code></a><a href="Reference/Global_Objects/Array/filter" title="filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。"><code>Array.prototype.filter</code></a><a href="Reference/Functions/Arrow_functions" title="箭头函数表达式的语法比函数表达式更简洁并且没有自己的thisargumentssuper或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方并且它们不能用作构造函数。">箭头函数</a><a href="Reference/Operators/Spread_operator" title="REDIRECT Spread syntax">展开语法</a>.。</p>
</div>
<p></p> <p></p>
<p><strong>数组推导式</strong>是一种 JavaScript 表达式语法,使用它,你可以在一个原有数组的基础上快速的构造出一个新的数组。但是它已经从标准和火狐中移除。不要用它!</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>在数组推导式内部,可以使用下面两种子语句:</p>
<ul>
<li><a href="Reference/Statements/for...of">for...of</a></li>
<li><a href="Reference/Statements/if...else">if</a></li>
</ul>
<p>每个 <code>for-of</code> 语句都放在与其配对的 <code>if</code> 语句(可以有多个,也可以完全省略)的左边,每个数组推导式中可以包含多组这样的配对,但最终选取的表达式值只能有一个,且这个值(也可以是个数组推导式,也就是说可以嵌套)只能放在推导式的最右边,紧靠着右中括号。</p>
<h2 id="示例">示例</h2>
<h3 id="基本的数组推导式写法">基本的数组推导式写法</h3>
<pre><code class="language-js">[for (i of [ 1, 2, 3 ]) i*i ];
// [ 1, 4, 9 ]
var abc = [ "A", "B", "C" ];
[for (letters of abc) letters.toLowerCase()];
// [ "a", "b", "c" ]</code></pre>
<h3 id="带有_if_语句的数组推导式">带有 if 语句的数组推导式</h3>
<pre><code class="language-javascript">var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
[for (year of years) if (year &gt; 2000) year];
// [ 2006, 2010, 2014 ]
[for (year of years) if (year &gt; 2000) if(year &lt; 2010) year];
// [ 2006], 和下面的写法等效:
[for (year of years) if (year &gt; 2000 &amp;&amp; year &lt; 2010) year];
// [ 2006]
</code></pre>
<h3 id="用数组推导式比用数组的_map、filter_方法更简洁">用数组推导式比用数组的 <code>map</code><code>filter</code> 方法更简洁</h3>
<p>对比数组的 <a href="Reference/Global_Objects/Array/map" title="map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。"><code>map</code></a><a href="Reference/Global_Objects/Array/filter" title="filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。"><code>filter</code></a> 方法:</p>
<pre><code class="language-javascript">var numbers = [ 1, 2, 3 ];
numbers.map(function (i) { return i * i });
[for (i of numbers) i*i ];
// 返回值都是 [ 1, 4, 9 ]
numbers.filter(function (i) { return i &lt; 3 });
[for (i of numbers) if (i &lt; 3) i];
// 返回值都是 [ 1, 2 ]
</code></pre>
<h3 id="带有两个数组的数组推导式">带有两个数组的数组推导式</h3>
<p>用两个 <code>for-of</code> 语句迭代两个不同的数组:</p>
<pre><code class="language-javascript">var numbers = [ 1, 2, 3 ];
var letters = [ "a", "b", "c" ];
var cross = [for (i of numbers) for (j of letters) i+j];
// [ "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c" ]
var grid = [for (i of numbers) [for (j of letters) i+j]];
// [
// ["1a", "1b", "1c"],
// ["2a", "2b", "2c"],
// ["3a", "3b", "3c"]
// ]
[for (i of numbers) if (i &gt; 1) for (j of letters) if(j &gt; "a") i+j]
// ["2b", "2c", "3b", "3c"],和下面的写法<strong>等效</strong>
[for (i of numbers) for (j of letters) if (i &gt; 1) if(j &gt; "a") i+j]
// ["2b", "2c", "3b", "3c"]
[for (i of numbers) if (i &gt; 1) [for (j of letters) if(j &gt; "a") i+j]]
// [["2b", "2c"], ["3b", "3c"]],和下面的写法<strong>不等效</strong>
[for (i of numbers) [for (j of letters) if (i &gt; 1) if(j &gt; "a") i+j]]
// [[], ["2b", "2c"], ["3b", "3c"]]
</code></pre>
<h2 id="规范">规范</h2>
<p>最初起草在ECMAScript 6草案中但在第27版2014年8月中被移除。 请参阅ES 6的旧修订版的规范语义。</p>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<div class="hidden"><span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>本页的浏览器兼容性表都是基于结构化数据,如果你想更新数据.可以查看</span> <a class="external" href="https://github.com/mdn/browser-compat-data" rel="noopener">https://github.com/mdn/browser-compat-data</a> <span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>并且请给我们发送合并请求</span>.</div>
<p></p><div class="bc-data"><a class="bc-github-link external" href="https://github.com/mdn/browser-compat-data" rel="noopener">Update compatibility data on GitHub</a><table class="bc-table bc-table-js"><thead><tr class="bc-platforms"><td></td><th class="bc-platform-desktop" colspan="6"><span>Desktop</span></th><th class="bc-platform-mobile" colspan="7"><span>Mobile</span></th><th class="bc-platform-server" colspan="1"><span>Server</span></th></tr><tr class="bc-browsers"><td></td><th class="bc-browser-chrome"><span class="bc-head-txt-label bc-head-icon-chrome">Chrome</span></th><th class="bc-browser-edge"><span class="bc-head-txt-label bc-head-icon-edge">Edge</span></th><th class="bc-browser-firefox"><span class="bc-head-txt-label bc-head-icon-firefox">Firefox</span></th><th class="bc-browser-ie"><span class="bc-head-txt-label bc-head-icon-ie">Internet Explorer</span></th><th class="bc-browser-opera"><span class="bc-head-txt-label bc-head-icon-opera">Opera</span></th><th class="bc-browser-safari"><span class="bc-head-txt-label bc-head-icon-safari">Safari</span></th><th class="bc-browser-webview_android"><span class="bc-head-txt-label bc-head-icon-webview_android">Android webview</span></th><th class="bc-browser-chrome_android"><span class="bc-head-txt-label bc-head-icon-chrome_android">Chrome for Android</span></th><th class="bc-browser-edge_mobile"><span class="bc-head-txt-label bc-head-icon-edge_mobile">Edge Mobile</span></th><th class="bc-browser-firefox_android"><span class="bc-head-txt-label bc-head-icon-firefox_android">Firefox for Android</span></th><th class="bc-browser-opera_android"><span class="bc-head-txt-label bc-head-icon-opera_android">Opera for Android</span></th><th class="bc-browser-safari_ios"><span class="bc-head-txt-label bc-head-icon-safari_ios">Safari on iOS</span></th><th class="bc-browser-samsunginternet_android"><span class="bc-head-txt-label bc-head-icon-samsunginternet_android">Samsung Internet</span></th><th class="bc-browser-nodejs"><span class="bc-head-txt-label bc-head-icon-nodejs">Node.js</span></th></tr></thead><tbody><tr><th scope="row">Array comprehensions <div class="bc-icons"><abbr class="only-icon" title="Deprecated. Not for use in new websites."><span>Deprecated</span><i class="ic-deprecated"></i></abbr><abbr class="only-icon" title="Non-standard. Expect poor cross-browser support."><span>Non-standard</span><i class="ic-non-standard"></i></abbr></div></th><td class="bc-supports-no bc-browser-chrome"><span class="bc-browser-name">Chrome</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-edge"><span class="bc-browser-name">Edge</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-firefox"><span class="bc-browser-name">Firefox</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>30 — 58</td><td class="bc-supports-no bc-browser-ie"><span class="bc-browser-name">IE</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-opera"><span class="bc-browser-name">Opera</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-safari"><span class="bc-browser-name">Safari</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-webview_android"><span class="bc-browser-name">WebView Android</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-chrome_android"><span class="bc-browser-name">Chrome Android</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-edge_mobile"><span class="bc-browser-name">Edge Mobile</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-firefox_android"><span class="bc-browser-name">Firefox Android</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>30 — 58</td><td class="bc-supports-no bc-browser-opera_android"><span class="bc-browser-name">Opera Android</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-safari_ios"><span class="bc-browser-name">Safari iOS</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-samsunginternet_android"><span class="bc-browser-name">Samsung Internet Android</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-no bc-browser-nodejs"><span class="bc-browser-name">nodejs</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td></tr></tbody></table><section class="bc-legend" id="sect1"><h3 class="offscreen" id="Legend">Legend</h3><dl><dt><span class="bc-supports-no bc-supports">
<abbr class="bc-level bc-level-no only-icon" title="No support">
<span>No support</span>
 
</abbr></span></dt><dd>No support</dd><dt><abbr class="only-icon" title="Non-standard. Expect poor cross-browser support."><span>Non-standard. Expect poor cross-browser support.</span><i class="ic-non-standard"></i></abbr></dt><dd>Non-standard. Expect poor cross-browser support.</dd><dt><abbr class="only-icon" title="Deprecated. Not for use in new websites."><span>Deprecated. Not for use in new websites.</span><i class="ic-deprecated"></i></abbr></dt><dd>Deprecated. Not for use in new websites.</dd></dl></section></div><p></p>
<h2 id="同旧版的JS1.7JS1.8数组推导的不同之处">同旧版的JS1.7/JS1.8数组推导的不同之处</h2>
<p> </p>
<div class="warning">JS1.7/JS1.8数组推导 在Gecko的46版本中已经被移除了 (<a class="external" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1220564" rel="noopener" title="FIXED: Remove legacy array/generator comprehension.">bug 1220564</a>).</div>
<p><strong>旧版数组推导语法 (请不要再使用了!):</strong></p>
<pre><code class="language-js example-bad">[X for (Y in Z)]
[X for each (Y in Z)]
[X for (Y of Z)]
</code></pre>
<p>不同点:</p>
<ul>
<li>ESNext数组推导为每个"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, each iteration creates a fresh binding for x. </code></li>
</ul>
</li>
<li>ESNext 同"for"进行赋值而取代了旧的赋值表达式.
<ul>
<li>Old: <code>[i * 2 for (i of numbers)]</code></li>
<li>New: <code>[for (i of numbers) i * 2]</code></li>
</ul>
</li>
<li>ESNext数组推导可由多个if和for组成</li>
<li>ESNext数组推导只和<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>
<p>点击查看 <a class="external" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1220564#c42" rel="noopener">Bug 1220564, comment 42</a> 并提出建设性建议.</p>
<h2 id="See_also" name="See_also">相关链接</h2>
<ul>
<li><a href="Reference/Statements/for...of"><code>for...of</code></a></li>
<li><a href="Reference/Operators/Generator_comprehensions" title="生成器推导语法是一种JavaScript表达式它允许您基于现有的可迭代对象快速组合新的生成器函数。">生成器推导式</a></li>
</ul>
</article>