実行環境 Node.js 15.2.1

公開日 January 4, 2021, GMT+9

更新日 January 13, 2021, GMT+9

コード例の出力としてconsole.logを使用しています。

使用方法がわからない場合は以下のページを参照してからコード例を確認してください。

console.logの使用方法

こちらはArrayオブジェクト(配列)のsliceメソッドのページです。 Stringオブジェクト(文字列)のsliceメソッドは Stringオブジェクト(文字列)のsliceメソッドの使用方法 を参照してください。

slice(Array、配列)

このページでは豊富な例を用いてJavaScript(js)のArrayオブジェクトのsliceの使い方を学ぶことができます。

JavaScript(js)のsliceはArrayオブジェクト(配列)のメソッドの1つです。
呼び出し元の配列に対して浅いコピーを行った配列を戻り値(返り値)として返します。
任意指定の第1引数と第2引数に呼び出し元の配列のインデックスを指定することにより、コピーを行う範囲を指定することができます。

呼び出し元の配列には変更を行わないイミュータブルなメソッドです。

TL;DR

基本

// 呼び出し元の配列の浅いコピーを返します
const array1 = [1, 2, 3, 4, 5];
const sliced_array1 = array1.slice();
console.log(sliced_array1);
==> [ 1, 2, 3, 4, 5 ]



const array2 = [{ id: 1, name: 'js' }, { id: 2, name: 'py' }];
const sliced_array2 = array2.slice();
console.log(sliced_array2);
==> [ { id: 1, name: 'js' }, { id: 2, name: 'py' } ]

コピー範囲の指定

// 第1引数にコピーを始めるインデックスを指定します
const array1 = [0, 1, 2, 3, 4];
const sliced_array1 = array1.slice(2);
console.log(sliced_array1);
==> [ 2, 3, 4 ]



// 第2引数にはコピーの終わりのインデックスを指定します
// このインデックスの要素はコピーに含まれません
const array2 = [0, 1, 2, 3, 4];
const sliced_array2 = array2.slice(2, 4);
console.log(sliced_array2);
==> [ 2, 3 ]



const array3 = [[0, 1], [2, 3], [4, 5]];
const sliced_array3 = array3.slice(0, 2);
console.log(sliced_array3);
==> [ [ 0, 1 ], [ 2, 3 ] ]



// -1は配列の最後尾のインデックスとなる
const array4 = ['js', 'ts', 'py', 'go', 'java'];
const sliced_array4 = array4.slice(2, -1);
console.log(sliced_array4);
==> [ 'py', 'go' ]



// 第2引数が0以上の値で第1引数より小さい場合
const array5 = [10, 20, 30, 40, 50];
const sliced_array5 = array5.slice(2, 0);
console.log(sliced_array5);
==> []



// 第2引数が配列の長さより長い場合
const array6 = [10, 20, 30, 40, 50];
const sliced_array6 = array6.slice(2, 100);
console.log(sliced_array6);
==> [ 30, 40, 50 ]

浅いコピーの注意点

const array1 = [0, 1, 2, { 'id': 100 }];
const sliced_array1 = array1.slice();
console.log(sliced_array1);
==> [ 0, 1, 2, { id: 100 } ]

// プリミティブな要素の変更はコピー元の配列に影響しない
sliced_array1[0] += -1;
console.log(array1);
==> [ 0, 1, 2, { id: 100 } ]
console.log(sliced_array1);
==> [ -1, 1, 2, { id: 100 } ]

// オブジェクトである要素の値の変更はコピー元の配列に影響する
sliced_array1[3].id = 999;
console.log(array1);
==> [ 0, 1, 2, { id: 999 } ]
console.log(sliced_array1);
==> [ -1, 1, 2, { id: 999 } ]



// コピー元配列(もしくはコピーした配列)への影響を防ぐ方法
const array2 = [0, 1, 2, { 'id': 100 }];
const sliced_array2 = array2.slice();

// 別のオブジェクトを代入する
sliced_array2[3] = { id: 999 };
console.log(array2);
==> [ 0, 1, 2, { id: 100 } ]
console.log(sliced_array2);
==> [ 0, 1, 2, { id: 999 } ]

解説

基本

sliceメソッドは呼び出し元の配列のコピーを戻り値(返り値)として返します。

このコピーは 浅いコピー(shallow copy、シャローコピー) です。
配列の要素のプリミティブではない値(配列やオブジェクトなど)を変更する際には、 後の項で解説している浅いコピーの注意点を意識して処理してください。

const array1 = ['javascript', 'python', 'typescript'];
const sliced_array1 = array1.slice();
console.log(sliced_array1);
==> [ 'javascript', 'python', 'typescript' ]



const array2 = [[0, 1], [2, 3]];
const sliced_array2 = array2.slice();
console.log(sliced_array2);
==> [ [ 0, 1 ], [ 2, 3 ] ]

コピー範囲の指定

sliceメソッドの第2引数と第3引数は任意指定の引数です。

第2引数のみを指定すると、指定したインデックスの位置から末尾までの要素をコピーする範囲として指定します。
第3引数も指定すると、第2引数で指定したインデックスから第3引数で指定したインデックスの要素の手前の要素までをコピー範囲とします。

// 第1引数のみの指定
const array1 = ['A', 'B', 'C', 'D', 'E'];
const sliced_array1 = array1.slice(2);
console.log(sliced_array1);
==> [ 'C', 'D', 'E' ]



// 第1引数と第2引数の指定
const array2 = ['A', 'B', 'C', 'D', 'E'];
const sliced_array2 = array2.slice(2, 4);
console.log(sliced_array2);
==> [ 'C', 'D' ]



// 第2引数が第1引数より小さい場合
const array3 = [0, 1, 2, 3, 4, 5];
const sliced_array3 = array3.slice(2, 0);
console.log(sliced_array3);
==> []



// 第2引数が配列の長さより長い場合
const array4 = [0, 1, 2, 3, 4, 5];
const sliced_array4 = array4.slice(2, 8);
console.log(sliced_array4);
==> [ 2, 3, 4, 5 ]

浅いコピーの注意点

sliceメソッドは呼び出し元の配列の浅いコピーを戻り値として返します。
そのため、プリミティブではない配列の要素(配列やオブジェクト)に含まれる要素を変更すると、 コピー元もしくはコピーした配列へも影響をあたえます。

この問題点を防ぐ方法は複数ありますが、 このページではプリミティブではない値の要素だけでなくその値自体を変更する方法を紹介します。
使用する場面によって適切な方法を選択してください。

const array1 = [0, false, 'js', { 'name': 'javascript' }];
const sliced_array1 = array1.slice();
console.log(sliced_array1);
==> [ 0, false, 'js', { name: 'javascript' } ]

// プリミティブな要素の変更はコピーした配列に影響しない
array1[0] += -100;
console.log(array1);
==> [ -100, false, 'js', { name: 'javascript' } ]
console.log(sliced_array1);
==> [ 0, false, 'js', { name: 'javascript' } ]

// オブジェクトである要素の値の変更はコピーした配列に影響する
array1[3].name = 'TypeScript';
console.log(array1);
==> [ -100, false, 'js', { name: 'TypeScript' } ]
console.log(sliced_array1);
==> [ 0, false, 'js', { name: 'TypeScript' } ]




// コピーした配列(もしくはコピー元配列)への影響を防ぐ方法
const array2 = [0, false, 'js', { 'name': 'javascript' }];
const sliced_array2 = array2.slice();

// 別のオブジェクトを代入する
array2[3] = { name: 'TypeScript' };
console.log(array2);
==> [ 0, false, 'js', { name: 'TypeScript' } ]
console.log(sliced_array2);
==> [ 0, false, 'js', { name: 'javascript' } ]

1次情報

Array.prototype.slice() - MDN web docs

Primitive (プリミティブ) - MDN web docs

Object (オブジェクト) - MDN web docs