diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/javascript/reference/global_objects/array/slice | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/zh-cn/web/javascript/reference/global_objects/array/slice')
-rw-r--r-- | files/zh-cn/web/javascript/reference/global_objects/array/slice/index.html | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/slice/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/slice/index.html new file mode 100644 index 0000000000..eb68df4907 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/slice/index.html @@ -0,0 +1,253 @@ +--- +title: Array.prototype.slice() +slug: Web/JavaScript/Reference/Global_Objects/Array/slice +tags: + - Array + - JavaScript + - Prototype + - 原型 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/slice +--- +<div>{{JSRef}}</div> + +<p><code><strong title="切片">slice()</strong></code> 方法返回一个新的数组对象,这一对象是一个由 <code>begin</code> 和 <code>end</code> 决定的原数组的<strong>浅拷贝</strong>(包括 <code>begin</code>,不包括<code>end</code>)。原始数组不会被改变。</p> + +<div>{{EmbedInteractiveExample("pages/js/array-slice.html")}}</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 href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><var>arr</var>.slice([<var>begin</var>[, <var>end</var>]])</pre> + +<h2 id="参数">参数</h2> + +<dl> + <dt><code>begin</code> {{optional_inline}}</dt> + <dd>提取起始处的索引(从 <code>0</code> 开始),从该索引开始提取原数组元素。</dd> + <dd>如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,<code>slice(-2)</code> 表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。</dd> + <dd>如果省略 <code>begin</code>,则 <code>slice</code> 从索引 <code>0</code> 开始。</dd> + <dd>如果 <code>begin</code> 超出原数组的索引范围,则会返回空数组。</dd> +</dl> + +<dl> + <dt><code>end</code> {{optional_inline}}</dt> + <dd>提取终止处的索引(从 <code>0</code> 开始),在该索引处结束提取原数组元素。<code>slice</code> 会提取原数组中索引从 <code>begin</code> 到 <code>end</code> 的所有元素(包含 <code>begin</code>,但不包含 <code>end</code>)。</dd> + <dd><code>slice(1,4)</code> 会提取原数组中从第二个元素开始一直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。</dd> + <dd>如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 <code>slice(-2,-1)</code> 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。</dd> + <dd>如果 <code>end</code> 被省略,则 <code>slice</code> 会一直提取到原数组末尾。</dd> + <dd>如果 <code>end</code> 大于数组的长度,<code>slice</code> 也会一直提取到原数组末尾。</dd> +</dl> + +<h3 id="返回值">返回值</h3> + +<p>一个含有被提取元素的新数组。</p> + +<h2 id="描述">描述</h2> + +<p><code>slice</code> 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:</p> + +<ul> + <li>如果该元素是个对象引用 (不是实际的对象),<code>slice</code> 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。</li> +</ul> + +<ul> + <li>对于字符串、数字及布尔值来说(不是 {{jsxref("Global_Objects/String", "String")}}、{{jsxref("Global_Objects/Number", "Number")}} 或者 {{jsxref("Boolean")}} 对象),<code>slice</code> 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。</li> +</ul> + +<p>如果向两个数组任一中添加了新元素,则另一个不会受到影响。</p> + +<h2 id="Examples" name="Examples">示例</h2> + +<h3 id="返回现有数组的一部分">返回现有数组的一部分</h3> + +<pre class="brush: js notranslate">var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']; +var citrus = fruits.slice(1, 3); + +// fruits contains ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'] +// citrus contains ['Orange','Lemon'] +</pre> + +<div class="standardNoteBlock"> +<p class="syntaxbox"><strong>译者注:citrus</strong> <em>[n.]</em> 柑橘类果实</p> +</div> + +<h3 id="使用_slice">使用 <code>slice</code></h3> + +<p>在下例中, <code>slice</code> 从 <code>myCar</code> 中创建了一个新数组<code>newCar</code>。两个数组都包含了一个 <code>myHonda</code> 对象的引用。当 <code>myHonda</code> 的 <code>color</code> 属性改变为 <code>purple</code>,则两个数组中的对应元素都会随之改变。</p> + +<pre class="brush: js notranslate">// 使用 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); +</pre> + +<p>上述代码输出:</p> + +<pre class="brush: js notranslate"> 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 +</pre> + +<h2 id="Array-like" name="Array-like">类数组(Array-like)对象</h2> + +<p><code>slice</code> 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。 一个函数中的 {{jsxref("Functions/arguments", "arguments")}} 就是一个类数组对象的例子。</p> + +<pre class="brush: js notranslate">function list() { + return Array.prototype.slice.call(arguments); +} + +var list1 = list(1, 2, 3); // [1, 2, 3] +</pre> + +<p>除了使用 <code>Array.prototype.slice.call(</code><code>arguments</code><code>)</code>,你也可以简单的使用 <code>[].slice.call(arguments)</code> 来代替。另外,你可以使用 <code>bind</code> 来简化该过程。</p> + +<pre class="brush: js notranslate">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] +</pre> + +<h2 id="精简跨浏览器行为">精简跨浏览器行为</h2> + +<p>根据规范,使用 <code>Array.prototype.slice</code> 转换宿主对象(如 DOM 对象)时,不必遵循 Mozilla 的默认行为,即可以转化任何符合条件的伪数组宿主对象为数组,IE < 9 没有遵循,而 IE9 + 遵循这个行为,但是稍加改造可以使其在跨浏览器使用时更可靠。只要其他现代浏览器继续支持该行为,目前 IE 9+、FireFox、Chrome、Safari 以及 Opera 都支持,开发者在使用下面代码时遍历 DOM 时就不会被该方法的字面意义误导,即 IE < 9 不能转化 DOM Collections。开发者可以安全地根据语义知道该方法的实际上的标准行为。(下面的代码还修正了 IE 中 <code>slice()</code> 方法第二个参数不允许为显式的 {{jsxref("Global_Objects/null", "null")}}/{{jsxref("Global_Objects/undefined", "undefined")}} 值的问题,其他现代浏览器,包括 IE9+ 都允许)。</p> + +<pre class="brush: js notranslate">/** + * Shim for "fixing" IE's lack of support (IE < 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 < 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 < 9 + _slice.call(document.documentElement); + } catch (e) { // Fails in IE < 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 < 9) + Array.prototype.slice = function(begin, end) { + // IE < 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 >= 0) ? start : Math.max(0, len + start); + + // Handle negative value for "end" + var upTo = (typeof end == 'number') ? Math.min(end, len) : len; + if (end < 0) { + upTo = len + end; + } + + // Actual expected size of the slice + size = upTo - start; + + if (size > 0) { + cloned = new Array(size); + if (this.charAt) { + for (i = 0; i < size; i++) { + cloned[i] = this.charAt(start + i); + } + } else { + for (i = 0; i < size; i++) { + cloned[i] = this[start + i]; + } + } + } + + return cloned; + }; + } +}()); +</pre> + +<h2 id="规范" style="margin-bottom: 20px; line-height: 30px;">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">规范</th> + <th scope="col">状态</th> + <th scope="col">备注</th> + </tr> + <tr> + <td>{{SpecName('ES3')}}</td> + <td>{{Spec2('ES3')}}</td> + <td>Initial definition.<br> + Implemented in JavaScript 1.2</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-15.4.4.10', 'Array.prototype.slice')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-array.prototype.slice', 'Array.prototype.slice')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-array.prototype.slice', 'Array.prototype.slice')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性" style="margin-bottom: 20px; line-height: 30px;">浏览器兼容性</h2> + +<div> + + +<p>{{Compat("javascript.builtins.Array.slice")}}</p> +</div> + +<h2 id="See_also" name="See_also" style="margin-bottom: 20px; line-height: 30px;">相关链接</h2> + +<ul> + <li>{{jsxref("Array.prototype.splice()")}}</li> + <li>{{jsxref("Function.prototype.call()")}}</li> + <li>{{jsxref("Function.prototype.bind()")}}</li> +</ul> |