--- title: Array.prototype.slice() slug: Web/JavaScript/Reference/Global_Objects/Array/slice tags: - Array - JavaScript - Method - Prototype - Reference translation_of: Web/JavaScript/Reference/Global_Objects/Array/slice --- <div>{{JSRef}}</div> <p><code><strong>slice()</strong></code> 方法會回傳一個新陣列物件,為原陣列選擇之 <code>begin</code> 至 <code>end</code>(不含 <code>end</code>)部分的淺拷貝(shallow copy)。而原本的陣列將不會被修改。</p> <div>{{EmbedInteractiveExample("pages/js/array-slice.html")}}</div> <h2 id="語法">語法</h2> <pre class="syntaxbox"><var>arr</var>.slice(<em>[</em><var>begin[</var>, <var>end]]</var>) </pre> <h3 id="參數">參數</h3> <dl> <dt><code>begin</code> {{optional_inline}}</dt> <dd>自哪一個索引(起始為 0)開始提取拷貝。可使用負數索引,表示由陣列的最末項開始提取。<code>slice(-2)</code> 代表拷貝陣列中的最後兩個元素。假如 <code>begin</code> 為 undefined,則 <code>slice</code> 會從索引 <code>0</code> 開始提取。</dd> <dt><code>end</code> {{optional_inline}}</dt> <dd>至哪一個索引(起始為 0)<em>之前</em>停止提取。<code>slice</code> 提取但不包含至索引 <code>end</code>。舉例來說,<code>slice(1,4)</code> 提取了陣列中第二個元素至第四個元素前為止(元素索引 1、2 以及 3)來拷貝。可使用負數索引,表示由陣列的最末項開始提取。<code>slice(2,-1)</code> 代表拷貝陣列中第三個元素至倒數第二個元素。若省略了 <code>end</code>,則 <code>slice</code> 會提取至陣列的最後一個元素(<code>arr.length</code>)。假如 <code>end</code> 大於陣列的長度,<code>slice</code> 會提取至陣列的最後一個元素(<code>arr.length</code>)。</dd> </dl> <h3 id="回傳值">回傳值</h3> <p>一個包含提取之元素的新陣列。</p> <h2 id="說明">說明</h2> <p><code>slice</code> 不會修改原本的陣列,而是回傳由原本的陣列淺層複製的元素。原始陣列的元素會按照下列規則拷貝:</p> <ul> <li>如果該元素是個對象引用(不是實際的對象),<code>slice</code> 會拷貝這個對象引用到新的陣列內。兩個對象引用都引用了同一個對象。如果被引用的對象發生改變,則新的和原來的陣列中的這個元素也會發生改變。</li> <li>對於字串、數字、布林來說 (不是 <a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String"><code>String</code></a>、<a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Number"><code>Number</code></a> 或者 <a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Boolean"><code>Boolean</code></a> 對象), <code>slice</code> 會拷貝這些值到新的陣列內。在別的陣列內修改這些字串、數字或是布林,將不會影響另一個陣列。</li> </ul> <p>如果添加了新的元素到另一個陣列內,則另一個不會受到影響。</p> <h2 id="範例">範例</h2> <h3 id="Return_a_portion_of_an_existing_array">Return a portion of an existing array</h3> <pre class="brush: js">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> <h3 id="Using_slice">Using <code>slice</code></h3> <p>In the following example, <code>slice</code> creates a new array, <code>newCar</code>, from <code>myCar</code>. Both include a reference to the object <code>myHonda</code>. When the color of <code>myHonda</code> is changed to purple, both arrays reflect the change.</p> <pre class="brush: js">// Using slice, create newCar from myCar. 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); // Display the values of myCar, newCar, and the color of myHonda // referenced from both arrays. console.log('myCar = ' + JSON.stringify(myCar)); console.log('newCar = ' + JSON.stringify(newCar)); console.log('myCar[0].color = ' + myCar[0].color); console.log('newCar[0].color = ' + newCar[0].color); // Change the color of myHonda. myHonda.color = 'purple'; console.log('The new color of my Honda is ' + myHonda.color); // Display the color of myHonda referenced from both arrays. console.log('myCar[0].color = ' + myCar[0].color); console.log('newCar[0].color = ' + newCar[0].color); </pre> <p>This script writes:</p> <pre class="brush: js">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)物件">類陣例(Array-like)物件</h2> <p><code>slice</code> method can also be called to convert Array-like objects / collections to a new Array. You just bind the method to the object. The {{jsxref("Functions/arguments", "arguments")}} inside a function is an example of an 'array-like object'.</p> <pre class="brush: js">function list() { return Array.prototype.slice.call(arguments); } var list1 = list(1, 2, 3); // [1, 2, 3] </pre> <p>Binding can be done with the .<code>call</code> function of {{jsxref("Function.prototype")}} and it can also be reduced using <code>[].slice.call(arguments)</code> instead of <code>Array.prototype.slice.call</code>. Anyway, it can be simplified using {{jsxref("Function.prototype.bind", "bind")}}.</p> <pre class="brush: js">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="Streamlining_cross-browser_behavior">Streamlining cross-browser behavior</h2> <p>Although host objects (such as DOM objects) are not required by spec to follow the Mozilla behavior when converted by <code>Array.prototype.slice</code> and IE < 9 does not do so, versions of IE starting with version 9 do allow this. “Shimming” it can allow reliable cross-browser behavior. As long as other modern browsers continue to support this ability, as currently do IE, Mozilla, Chrome, Safari, and Opera, developers reading (DOM-supporting) slice code relying on this shim will not be misled by the semantics; they can safely rely on the semantics to provide the now apparently <em>de facto</em> standard behavior. (The shim also fixes IE to work with the second argument of <code>slice()</code> being an explicit {{jsxref("null")}}/{{jsxref("undefined")}} value as earlier versions of IE also did not allow but all modern browsers, including IE >= 9, now do.)</p> <pre class="brush: js">/** * 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="規範">規範</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>{{SpecName('ES3')}}</td> <td>{{Spec2('ES3')}}</td> <td>Initial definition. 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="瀏覽器相容性">瀏覽器相容性</h2> <div> <p>{{Compat("javascript.builtins.Array.slice")}}</p> </div> <h2 id="參見">參見</h2> <ul> <li>{{jsxref("Array.prototype.splice()")}}</li> <li>{{jsxref("Function.prototype.call()")}}</li> <li>{{jsxref("Function.prototype.bind()")}}</li> </ul>