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

257 lines
19 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><code><strong title="切片">slice()</strong></code> 方法返回一个新的数组对象,这一对象是一个由 <code>begin</code><code>end</code>(不包括<code>end</code>)决定的原数组的<strong>浅拷贝</strong>。原始数组不会被改变。</div>
<div><iframe class="interactive interactive-js" frameborder="0" height="250" src="https://interactive-examples.mdn.mozilla.net/pages/js/array-slice.html" width="100%"></iframe></div>
<p class="hidden">The source for this interactive demo is stored in a GitHub repository. If you'd like to contribute to the interactive demo 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>
<h2 id="语法">语法</h2>
<pre><code class="language-javascript">arr.slice();
// [0, end]
arr.slice(begin);
// [begin, end]
arr.slice(begin, end);
// [begin, end)
</code></pre>
<h2 id="Parameters" name="Parameters">参数</h2>
<dl>
<dt><code>begin</code> <span class="inlineIndicator optional optionalInline">可选</span></dt>
<dd>从该索引处开始提取原数组中的元素从0开始</dd>
<dd>如果该参数为负数,<code>则表示从原数组中的倒数第几个元素开始提取,</code><code>slice(-2)</code>表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。</dd>
<dd>如果省略 <code>begin</code>,则 <code>slice</code> 从索引 0 开始。</dd>
</dl>
<dl>
<dt><code>end</code><span class="inlineIndicator optional optionalInline">可选</span></dt>
<dd>在该索引处结束提取原数组元素从0开始<code>slice</code>会提取原数组中索引从 <code>begin</code> 到 <code>end </code>的所有元素包含begin但不包含end</dd>
<dd><code>slice(1,4)</code> 提取原数组中的第二个元素开始直到第四个元素的所有元素 (索引为 1, 2, 3的元素</dd>
<dd>如果该参数为负数, <code>则它表示在原数组中的倒数第几个元素结束抽取</code><code>slice(-2,-1)</code>表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。</dd>
<dd>如果 <code>end</code> 被省略,<code>则slice</code> 会一直提取到原数组末尾。</dd>
<dd>如果 <code>end 大于数组长度slice 也会一直提取到原数组末尾。</code></dd>
</dl>
<h3 id="返回值">返回值</h3>
<p>一个含有提取元素的新数组</p>
<h2 id="Description" name="Description">描述</h2>
<p><code>slice</code> 不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:</p>
<ul>
<li>如果该元素是个对象引用 (不是实际的对象),<code>slice</code> 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。</li>
</ul>
<ul>
<li>对于字符串、数字及布尔值来说(不是 <a href="Reference/Global_Objects/String" title="String 全局对象是一个用于字符串或一个字符序列的构造函数。"><code>String</code></a><a href="Reference/Global_Objects/Number" title="JavaScript 的 Number 对象是经过封装的能让你处理数字值的对象。Number 对象由 Number() 构造器创建。"><code>Number</code></a> 或者 <a href="Reference/Boolean" title="此页面仍未被本地化, 期待您的翻译!"><code>Boolean</code></a> 对象),<code>slice</code> 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。</li>
</ul>
<p>如果向两个数组任一中添加了新元素,则另一个不会受到影响。</p>
<h2 id="Examples" name="Examples">示例</h2>
<h3 id="Example:_Return_a_portion_of_an_existing_array" name="Example:_Return_a_portion_of_an_existing_array" style="line-height: 24px;">返回现有数组的一部分</h3>
<pre><code class="language-javascript">var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
var citrus = fruits.slice(1, 3);
// fruits contains ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
// citrus contains ['Orange','Lemon']
</code></pre>
<h3 id="Example:_Using_slice" name="Example:_Using_slice">使用 <code>slice</code></h3>
<p>在下例中, <code>slice从</code><code>myCar中创建了一个新数组</code><code>newCar</code>.两个数组都包含了一个<code>myHonda</code>对象的引用. 当<code>myHonda</code>的color属性改变为purple, 则两个数组中的对应元素都会随之改变.</p>
<pre><code class="language-javascript">// 使用slice方法从myCar中创建一个newCar.
var myHonda = { color: 'red', wheels: 4, engine: { cylinders: 4, size: 2.2 } };
var myCar = [myHonda, 2, "cherry condition", "purchased 1997"];
var newCar = myCar.slice(0, 2);
// 输出myCar, newCar,以及各自的myHonda对象引用的color属性.
console.log('myCar = ' + JSON.stringify(myCar));
console.log('newCar = ' + JSON.stringify(newCar));
console.log('myCar[0].color = ' + JSON.stringify(myCar[0].color));
console.log('newCar[0].color = ' + JSON.stringify(newCar[0].color));
// 改变myHonda对象的color属性.
myHonda.color = 'purple';
console.log('The new color of my Honda is ' + myHonda.color);
//输出myCar, newCar中各自的myHonda对象引用的color属性.
console.log('myCar[0].color = ' + myCar[0].color);
console.log('newCar[0].color = ' + newCar[0].color);
</code></pre>
<p>上述代码输出:</p>
<pre><code class="language-javascript">myCar = [{color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}, 2,
'cherry condition', 'purchased 1997']
newCar = [{color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}, 2]
myCar[0].color = red
newCar[0].color = red
The new color of my Honda is purple
myCar[0].color = purple
newCar[0].color = purple
</code></pre>
<h2 id="Array-like" name="Array-like">类数组Array-like对象</h2>
<p><code>slice</code> 方法可以用来将一个类数组Array-like对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。 一个函数中的 <code>arguments</code> 就是一个类数组对象的例子。</p>
<pre><code class="language-javascript">function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
</code></pre>
<p>除了使用 <code>Array.prototype.slice.call(</code><code>arguments</code><code>)</code>,你也可以简单的使用 <code>[].slice.call(arguments)</code> 来代替。另外,你可以使用 <code>bind</code> 来简化该过程。</p>
<pre><code class="language-javascript">var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);
function list() {
  return slice(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
</code></pre>
<h2 id="精简跨浏览器行为" style="margin-bottom: 20px; line-height: 30px;">精简跨浏览器行为</h2>
<p>根据规范,使用 <font face="Courier, Andale Mono, monospace">Array.prototype.slice</font> 转换宿主对象(如 DOM 对象)时不必遵循 Mozilla 的默认行为即可以转化任何符合条件的伪数组宿主对象为数组IE &lt; 9 没有遵循 IE9 + 遵循这个行为,但是稍加改造可以使其在跨浏览器使用时更可靠。只要其他现代浏览器继续支持该行为,目前 IE  9+、FireFox、Chrome、Safari 以及 Opera 都支持,开发者在使用下面代码时遍历 DOM 时就不会被该方法的字面意义误导,即 IE &lt; 9 不能转化 DOM Collections。开发者可以安全地根据语义知道该方法的实际上的标准行为。下面的代码还修正了 IE 中 <code>slice()</code> 方法第二个参数不允许为显式的 <a href="Reference/Global_Objects/null" title="值 null 特指对象的值未设置。它是 JavaScript 基本类型 之一。"><code>null</code></a>/<a href="Reference/Global_Objects/undefined" title="undefined是全局对象的一个属性。也就是说它是全局作用域的一个变量。undefined的最初值就是原始数据类型undefined。"><code>undefined</code></a> 值的问题其他现代浏览器包括IE9+都允许)。</p>
<pre><code class="language-javascript">/**
* Shim for "fixing" IE's lack of support (IE &lt; 9) for applying slice
* on host objects like NamedNodeMap, NodeList, and HTMLCollection
* (technically, since host objects have been implementation-dependent,
* at least before ES2015, IE hasn't needed to work this way).
* Also works on strings, fixes IE &lt; 9 to allow an explicit undefined
* for the 2nd argument (as in Firefox), and prevents errors when
* called on other DOM objects.
*/
(function () {
'use strict';
var _slice = Array.prototype.slice;
try {
// Can't be used with DOM elements in IE &lt; 9
_slice.call(document.documentElement);
} catch (e) { // Fails in IE &lt; 9
// This will work for genuine arrays, array-like objects,
// NamedNodeMap (attributes, entities, notations),
// NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes),
// and will not fail on other DOM objects (as do DOM elements in IE &lt; 9)
Array.prototype.slice = function(begin, end) {
// IE &lt; 9 gets unhappy with an undefined end argument
end = (typeof end !== 'undefined') ? end : this.length;
// For native Array objects, we use the native slice function
if (Object.prototype.toString.call(this) === '[object Array]'){
return _slice.call(this, begin, end);
}
// For array like object we handle it ourselves.
var i, cloned = [],
size, len = this.length;
// Handle negative value for "begin"
var start = begin || 0;
start = (start &gt;= 0) ? start : Math.max(0, len + start);
// Handle negative value for "end"
var upTo = (typeof end == 'number') ? Math.min(end, len) : len;
if (end &lt; 0) {
upTo = len + end;
}
// Actual expected size of the slice
size = upTo - start;
if (size &gt; 0) {
cloned = new Array(size);
if (this.charAt) {
for (i = 0; i &lt; size; i++) {
cloned[i] = this.charAt(start + i);
}
} else {
for (i = 0; i &lt; size; i++) {
cloned[i] = this[start + i];
}
}
}
return cloned;
};
}
}());
</code></pre>
<h2 id="规范" style="margin-bottom: 20px; line-height: 30px;">规范</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/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf" hreflang="en" lang="en" rel="noopener" title="ECMAScript 3rd Edition (ECMA-262)">ECMAScript 3rd Edition (ECMA-262)</a></td>
<td><span class="spec-Standard">Standard</span></td>
<td>Initial definition.<br/>
Implemented in JavaScript 1.2</td>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.10" hreflang="en" lang="en" rel="noopener">ECMAScript 5.1 (ECMA-262)<br/><small lang="zh-CN">Array.prototype.slice</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td> </td>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.slice" hreflang="en" lang="en" rel="noopener">ECMAScript 2015 (6th Edition, ECMA-262)<br/><small lang="zh-CN">Array.prototype.slice</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.slice" hreflang="en" lang="en" rel="noopener">ECMAScript Latest Draft (ECMA-262)<br/><small lang="zh-CN">Array.prototype.slice</small></a></td>
<td><span class="spec-Draft">Draft</span></td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性" style="margin-bottom: 20px; line-height: 30px;">浏览器兼容性</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"><code>slice</code></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>
1</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>
1</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>
Yes</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>
Yes</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>
Yes</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" style="margin-bottom: 20px; line-height: 30px;">相关链接</h2>
<ul>
<li><a href="Reference/Global_Objects/Array/splice" title="splice() 方法通过删除或替换现有元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。"><code>Array.prototype.splice()</code></a></li>
<li><a href="Reference/Global_Objects/Function/call" title="call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。"><code>Function.prototype.call</code></a></li>
<li><a href="Reference/Global_Objects/Function/bind" title="bind()方法创建一个新的函数在调用时设置this关键字为提供的值。并在调用新函数时将给定参数列表作为原函数的参数序列的前若干项。"><code>Function.prototype.bind</code></a></li>
<li><a class="external" href="https://github.com/xgqfrms-GitHub/ES6/tree/gh-pages/es6-in-deepth" rel="noopener">es6-in-deepth</a></li>
</ul>
</article>