.slice()

slice()メソッドは配列の一部分の浅いコピーを新しい配列オブジェクトにして返します。

文法

arr.slice(begin[, end])
引数 説明
begin

抜き出すを開始する0ベースのインデックスを指定します。

負のインデックスを指定すると、末尾から数えたbeginを指定することになります。 slice(-2)は、最後の2つの要素を抜き出します。

もし、beginを省略すると、インデックス0を指定したことになります。

end

抜き出しの終端を示す0ベースのインデックスを指定します。 ただし、sliceはendのインデックス要素を含みません。

slice(1,4)は2つ目の要素から4つ目の要素(インデックスが1、2、3の要素)までを抜き出します。

負のインデックスを指定すると、末尾から数えたendを指定することになります。 slice(2,-1)は、3つ目の要素から最後から2番目の要素を抜き出します。

endを省略すると、sliceは配列の最後までを抜き出します。

説明

sliceは元の配列の変更は行いませんが、 元の配列から切り取った要素のコピーを含む、"1階層"の新しいコピーを返します。 元の配列の要素は、下記のようにして新しい配列にコピーされます。

  • 抜き出す要素がオブジェクト参照(実際のオブジェクトでは無い)の場合、 sliceは新しい配列へオブジェクトの参照をコピーします。 元の配列と新しい配列は、両方とも同じオブジェクトを参照します。 もし、参照されているオブジェクトが変更されると、 その変更は新しい配列と元の配列の両方で確認することが出来ます。
  • 抜き出す要素が文字列または数値(String、Numberオブジェクトでは無い)の場合、 sliceは文字列と数値を新しい配列へコピーします。 一方の配列の文字列または数値が変更は、もう一方の配列に影響しません。

もし新しい要素がどちらかに追加されても、別の配列には影響しません。

例

例: 既存の配列の一部分を返す

// 果物サンプルから、柑橘類の一部分を抽出
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1, 3);

// puts --> ["Orange","Lemon"]

例: sliceの使用

下記の例では、sliceはmyCarから新しい配列であるnewCarを作成します。 どちらも、myHondaオブジェクトへの参照を含みます。 myHondaのcolorをpurpleに変更すると、 両方の配列に変更が反映されます。

// 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 = " + myCar.toSource());
console.log("newCar = " + newCar.toSource());
console.log("myCar[0].color = " + myCar[0].color);
console.log("newCar[0].color = " + newCar[0].color);

// myHondaのcolorを変更します。
myHonda.color = "purple";
console.log("The new color of my Honda is " + myHonda.color);

// 両方の配列から参照されているmyHondaのcolorを表示します。
console.log("myCar[0].color = " + myCar[0].color);
console.log("newCar[0].color = " + newCar[0].color);

このスクリプトは、次のように出力を行います。

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

配列のようなオブジェクト

また、sliceメソッドは配列のようなオブジェクト/コレクションを新しい配列へ変換するために呼び出すことも可能です。 そのオブジェクトへ、メソッドをバインドします。 関数内のargumentsは、"配列のようなオブジェクト"の一例とします。

function list() {
  return Array.prototype.slice.call(arguments, 0);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

バインドはFunction.prototypeの.call 関数を使用して行うことが可能です。 また、Array.prototype.slice.callを使用することで、 [].slice.call(arguments)の使用を抑えることも可能です。 さらに、bindを使用することで簡略化することが可能です。

var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);

function list() {
  return slice(arguments, 0);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

クロスブラウザの振る舞い

ホストオブジェクト(DOMオブジェクトのような)は、Array.prototype.sliceによる変換の際に、 Mozillaの振る舞いの仕様に従うことを必要とされているわけでは無く、IE9未満ではその振る舞いを行わず、 IE9以上ではその仕様に従います。 "shimming"(楔)をすることで、クロスブラウザの振る舞いを確かなものにします。

他のモダンブラウザがこの機能をサポートし続ける限り、 開発者がこの"shim"(楔)に依存したsliceのコードを読むこと(DOMサポート)は、セマンティクスによって誤解されることは無く、 それらは安全にセマンティクスを現在のデファクトスタンダードな振る舞いに依存することが可能です。(翻訳に自信なし) (また、この"shim"(楔)は、IEの古いバージョンでは許可されないが、IE >= 9を含む全てのモダンブラウザでは許可される、 IEのslice()の2つ目の引数を明示的にnull/undefined値にする動作を修正します。

/**
 * 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 ES6, 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: len + start;

            // Handle negative value for "end"
            var upTo = (end) ? end : 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;
        };
    }
}());

仕様

ブラウザ互換性

デスクトップ
機能 Chrome Firefox
(Gecko)
IE Opera Safari
基本 1.0 1.0 (1.7 or earlier) ◯ ◯ ◯
モバイル
機能 Android Chrome for
Android
Firefox
Mobile
IE
Mobile
Opera
Mobile
Safari
Mobile
基本 ◯ ◯ ◯ ◯ ◯ ◯

関連項目

 Back to top

© 2017 Mozilla Contributors
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.

このページは、ページトップのURL先のMozilla Developer Network(以下、MDN)のコンテンツを翻訳した内容を基に構成されています。 構成について異なる点も含まれますので、下記の項目を確認し、必要に応じて元のコンテンツをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。

  • 特定のブラウザに特化しすぎている情報やあまりにも古い情報、 または試験的に導入されているようなAPIや機能については、省略していることがあります。
  • 例やデモについて、実際にページ内で動作させる関係で一部ソースコードを変更している場合や、 その例で使用しているコンテンツの単語や文章などを日本人向けに変更しいてる場合があります。
  • MDNの更新頻度が高いため、元のコンテンツと比べ情報が古くなっている可能性があります。
  • "訳注:"などの断わりを入れた上で、日本人向けの情報の追記を行っている事があります。