2019-04-21 11:50:48 +08:00

291 lines
16 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></div>
<div> </div>
<p><code><strong>reduceRight()</strong></code> 方法接受一个函数作为累加器accumulator和数组的每个值从右到左将其减少为单个值。</p>
<div><iframe class="interactive interactive-js" frameborder="0" height="250" src="https://interactive-examples.mdn.mozilla.net/pages/js/array-reduce-right.html" width="100%"></iframe></div>
<p class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a class="external" href="https://github.com/mdn/interactive-examples" rel="noopener">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p>
<p>对于从左至右遍历的相似方法请参阅 <a href="Reference/Global_Objects/Array/reduce" title="reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。"><code>Array.prototype.reduce()</code></a>.</p>
<h2 id="语法">语法</h2>
<pre><code class="language-javascript"><code><em>arr</em>.reduceRight(<em>callback</em>[, <em>initialValue</em>])</code></code></pre>
<h3 id="参数">参数</h3>
<dl>
<dt><code>callback</code></dt>
<dd>一个回调函数,用来操作数组中的每个元素,可接受四个参数:
<dl>
<dt><code>previousValue</code></dt>
<dd>上一次调用回调的返回值,或提供的 <code>initialValue</code></dd>
<dt><code>currentValue</code></dt>
<dd>当前被处理的元素</dd>
<dt><code>index</code></dt>
<dd>当前处理元素的索引</dd>
<dt><code>array</code></dt>
<dd>调用 <code>reduce</code> 的数组</dd>
</dl>
</dd>
<dt><code>initialValue</code></dt>
<dd>可作为第一次调用回调 <code>callback</code> 的第一个参数</dd>
<dt>
<h3 id="返回值">返回值</h3>
</dt>
<dd>
<p>执行之后的返回值</p>
</dd>
</dl>
<h2 id="描述">描述</h2>
<p><code>reduceRight</code> 为数组中每个元素调用一次 <code>callback</code> 回调函数,但是数组中被删除的索引或从未被赋值的索引会跳过。回调函数接受四个参数:初始值(或上次调用回调的返回值)、当前元素值、当前索引,以及调用 <code>reduce</code> 的数组。</p>
<p>可以像下面这样调用 <code>reduceRight</code> 的回调函数 <code>callback</code></p>
<pre><code class="language-javascript">array.reduceRight(function(previousValue, currentValue, index, array) {
// ...
});
</code></pre>
<p>首次调用回调函数时,<code>previousValue</code><code>currentValue</code> 可以是两个值之一。如果调用 <code>reduceRight</code> 时提供了 <code>initialValue</code> 参数,则 <code>previousValue</code> 等于 <code>initialValue</code><code>currentValue</code> 等于数组中的最后一个值。如果没有提供 <code>initialValue</code> 参数,则 <code>previousValue</code> 等于数组最后一个值, <code>currentValue</code> 等于数组中倒数第二个值。</p>
<p>如果数组为空,且没有提供 <code>initialValue</code> 参数,将会抛出一个 <code>TypeError 错误。如果数组只有一个元素且没有提供</code> <code>initialValue </code>参数,或者提供了 <code>initialValue</code> 参数,但是数组为空将会直接返回数组中的那一个元素或 <code>initialValue</code> 参数,而不会调用 <code>callback</code></p>
<p>该函数的完整执行过程见下例:</p>
<pre><code class="language-javascript">[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
});
</code></pre>
<p>回调将会被调用四次,每次调用的参数及返回值如下:</p>
<table style="width: 100%;">
<thead>
<tr>
<th scope="col"> </th>
<th scope="col"><code>previousValue</code></th>
<th scope="col"><code>currentValue</code></th>
<th scope="col"><code>index</code></th>
<th scope="col"><code>array</code></th>
<th scope="col">return value</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">first call</th>
<td>4</td>
<td>3</td>
<td>3</td>
<td><code>[0,1,2,3,4]</code></td>
<td><font face="Courier New, Andale Mono, monospace"><span style="line-height: normal;">7</span></font></td>
</tr>
<tr>
<th scope="row">second call</th>
<td>7</td>
<td><code>2</code></td>
<td><code>2</code></td>
<td><code>[0,1,2,3,4]</code></td>
<td><font face="Courier New, Andale Mono, monospace"><span style="line-height: normal;">9</span></font></td>
</tr>
<tr>
<th scope="row">third call</th>
<td>9</td>
<td>1</td>
<td>1</td>
<td><code>[0,1,2,3,4]</code></td>
<td><font face="Courier New, Andale Mono, monospace"><span style="line-height: normal;">10</span></font></td>
</tr>
<tr>
<th scope="row">fourth call</th>
<td>10</td>
<td>0</td>
<td>0</td>
<td><code>[0,1,2,3,4]</code></td>
<td><code>10</code></td>
</tr>
</tbody>
</table>
<p><code>reduceRight</code> 返回值是最后一次调用回调的返回值(<code>10</code></p>
<p>如果提供了一个 <code>initialValue</code> 参数,则结果如下:</p>
<pre><code class="language-javascript">[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
}, 10);
</code></pre>
<table style="width: 100%;">
<thead>
<tr>
<th scope="col"> </th>
<th scope="col"><code>previousValue</code></th>
<th scope="col"><code>currentValue</code></th>
<th scope="col"><code>index</code></th>
<th scope="col"><code>array</code></th>
<th scope="col">return value</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">first call</th>
<td><code>10</code></td>
<td>4</td>
<td>4</td>
<td><code>[0,1,2,3,4]</code></td>
<td><code>14</code></td>
</tr>
<tr>
<th scope="row">second call</th>
<td>14</td>
<td>3</td>
<td>3</td>
<td><code>[0,1,2,3,4]</code></td>
<td><code>17</code></td>
</tr>
<tr>
<th scope="row">third call</th>
<td>17</td>
<td><code>2</code></td>
<td><code>2</code></td>
<td><code>[0,1,2,3,4]</code></td>
<td><code>19</code></td>
</tr>
<tr>
<th scope="row">fourth call</th>
<td>19</td>
<td>1</td>
<td>1</td>
<td><code>[0,1,2,3,4]</code></td>
<td><font face="Courier New, Andale Mono, monospace"><span style="line-height: normal;">20</span></font></td>
</tr>
<tr>
<th scope="row">fifth call</th>
<td>20</td>
<td>0</td>
<td>0</td>
<td><code>[0,1,2,3,4]</code></td>
<td><code>20</code></td>
</tr>
</tbody>
</table>
<p><code>reduceRight</code> 返回值为 20。</p>
<h2 id="示例">示例</h2>
<h3 id="例子:求一个数组中所有值的和">例子:求一个数组中所有值的和</h3>
<pre><code class="language-javascript">var total = [0, 1, 2, 3].reduceRight(function(a, b) {
return a + b;
});
// total == 6
</code></pre>
<h3 id="例子扁平化flatten一个元素为数组的数组">例子扁平化flatten一个元素为数组的数组</h3>
<pre><code class="language-javascript">var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
return a.concat(b);
}, []);
// flattened is [4, 5, 2, 3, 0, 1]
</code></pre>
<h3 id="例子reduce_与_reduceRight_之间的区别">例子reduce 与 reduceRight 之间的区别</h3>
<pre><code class="language-javascript">var a = ['1', '2', '3', '4', '5'];
var left = a.reduce(function(prev, cur) { return prev + cur; });
var right = a.reduceRight(function(prev, cur) { return prev + cur; });
console.log(left); // "12345"
console.log(right); // "54321"</code></pre>
<h2 id="兼容性旧环境Polyfill">兼容性旧环境Polyfill</h2>
<p><code>reduceRight</code> 被添加到 ECMA-262 标准第 5 版,因此它在某些实现环境中可能不被支持。把下面的代码添加到脚本开头可以解决此问题,从而允许在那些没有原生支持 <code>reduceRight</code> 的实现环境中使用它。</p>
<pre><code class="language-javascript">// Production steps of ECMA-262, Edition 5, 15.4.4.22
// Reference: http://es5.github.io/#x15.4.4.22
if ('function' !== typeof Array.prototype.reduceRight) {
Array.prototype.reduceRight = function(callback /*, initialValue*/) {
'use strict';
if (null === this || 'undefined' === typeof this) {
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length &gt;&gt;&gt; 0, k = len - 1, value;
if (arguments.length &gt;= 2) {
value = arguments[1];
} else {
while (k &gt;= 0 &amp;&amp; !(k in t)) {
k--;
}
if (k &lt; 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
value = t[k--];
}
for (; k &gt;= 0; k--) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
</code></pre>
<h2 id="规范">规范</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.22" hreflang="en" lang="en" rel="noopener">ECMAScript 5.1 (ECMA-262)<br/><small lang="zh-CN">Array.prototype.reduceRight</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td>Initial definition.<br/>
Implemented in JavaScript 1.8</td>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.reduceright" hreflang="en" lang="en" rel="noopener">ECMAScript 2015 (6th Edition, ECMA-262)<br/><small lang="zh-CN">Array.prototype.reduceRight</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td> </td>
</tr>
<tr>
<td><a class="external" href="https://tc39.github.io/ecma262/#sec-array.prototype.reduceright" hreflang="en" lang="en" rel="noopener">ECMAScript Latest Draft (ECMA-262)<br/><small lang="zh-CN">Array.prototype.reduceRight</small></a></td>
<td><span class="spec-Draft">Draft</span></td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<div>
<div class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a class="external" href="https://github.com/mdn/browser-compat-data" rel="noopener">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</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"><a href="Reference/Global_Objects/Array/reduceRight"><code>reduceRight</code></a></th><td class="bc-supports-yes bc-browser-chrome"><span class="bc-browser-name">Chrome</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-edge"><span class="bc-browser-name">Edge</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
12</td><td class="bc-supports-yes bc-browser-firefox"><span class="bc-browser-name">Firefox</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
3</td><td class="bc-supports-yes bc-browser-ie"><span class="bc-browser-name">IE</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
9</td><td class="bc-supports-yes bc-browser-opera"><span class="bc-browser-name">Opera</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
10.5</td><td class="bc-supports-yes bc-browser-safari"><span class="bc-browser-name">Safari</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
4</td><td class="bc-supports-yes bc-browser-webview_android"><span class="bc-browser-name">WebView Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-chrome_android"><span class="bc-browser-name">Chrome Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-edge_mobile"><span class="bc-browser-name">Edge Mobile</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-firefox_android"><span class="bc-browser-name">Firefox Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
4</td><td class="bc-supports-yes bc-browser-opera_android"><span class="bc-browser-name">Opera Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-safari_ios"><span class="bc-browser-name">Safari iOS</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-samsunginternet_android"><span class="bc-browser-name">Samsung Internet Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-nodejs"><span class="bc-browser-name">nodejs</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td></tr></tbody></table><section class="bc-legend" id="sect1"><h3 class="offscreen" id="Legend">Legend</h3><dl><dt><span class="bc-supports-yes bc-supports">
<abbr class="bc-level bc-level-yes only-icon" title="Full support">
<span>Full support</span>
 
</abbr></span></dt><dd>Full support</dd></dl></section></div><p></p>
</div>
<h2 id="See_also" name="See_also">相关链接</h2>
<ul>
<li><a href="Reference/Global_Objects/Array/reduce" title="reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。"><code>Array.prototype.reduce()</code></a></li>
</ul>
</article>