JavaScript | 配列の一部をコピーして、新しい配列を作る(slice メソッド)

JavaScript JavaScript
スポンサーリンク

slice()配列から「一部分」を取り出して新しい配列を作るメソッドです。元の配列は変更しません(=非破壊)。初心者向けに一つずつ噛み砕いて、図・コード・練習問題付きで説明します。


1. 基本イメージ(まずは直感)

元の配列: [ A, B, C, D, E ]
インデックス:  0  1  2  3  4

slice(1, 4) をすると → [ B, C, D ]
(開始 1 から終了 4 の手前まで)
JavaScript
  • slice(start, end)
    • start:取り出しを始める位置(含む)
    • end:取り出しを終える位置(含まない:end の「手前」まで)
  • slice() に引数を何も渡さないと 配列全体のコピーになります。

2. 使い方パターン(コード例)

a) 引数が無い(丸ごとコピー)

const arr = [1, 2, 3];
const copy = arr.slice();
console.log(copy); // [1, 2, 3]
// arr と copy は別の配列(ただし中身がオブジェクトだと注意)
JavaScript

b) start だけ指定(start から最後まで)

const arr = ['a','b','c','d'];
console.log(arr.slice(2)); // ['c', 'd']  (インデックス2から最後)
JavaScript

c) start と end 両方指定(start から end-1 まで)

const arr = [10,20,30,40,50];
console.log(arr.slice(1, 4)); // [20, 30, 40] (インデックス1〜3)
JavaScript

3. マイナスのインデックス(よく使う便利技)

  • startend に負の数を渡すと 末尾から数える意味になります。
const arr = [0,1,2,3,4,5];
console.log(arr.slice(-2));   // [4,5]     (末尾から2つ)
console.log(arr.slice(2, -1)); // [2,3,4]  (インデックス2から末尾の1つ手前まで)
JavaScript

4. 範囲外や start >= end の場合の挙動

  • start が配列の長さ以上 → 空配列 [] が返る。
  • end が配列の長さより大きくても問題なし(最後まで取る)。
  • start >= end → 空配列 []

例:

[1,2,3].slice(5)     // []
[1,2,3].slice(2,2)  // []
[1,2,3].slice(2,10) // [3]
JavaScript

5. 重要な注意点:浅いコピー(shallow copy)

slice() が作るのは浅いコピーです。配列の要素が オブジェクトや配列(参照型) の場合、コピー先と元は「同じ中身(同じ参照)」を指します。だから内部のオブジェクトを変更すると元にも影響します。

const original = [{name:'A'}, {name:'B'}];
const part = original.slice(0,1);
part[0].name = 'Z';
console.log(original[0].name); // 'Z' ← 元にも影響した
JavaScript
  • 対処法(独立したコピーが欲しい場合):
    • 単純なオブジェクト列なら JSON を使う方法(注意:関数や特殊オブジェクトは潰れる) const deepCopy = JSON.parse(JSON.stringify(original));
    • 複雑な場合は専用の「深いコピー」関数(lodash の cloneDeep など)を使う。

6. slice() と似たメソッドとの違い(簡単まとめ)

  • splice():元の配列を変更して要素を取り出す(破壊的)。slice() は変更しない(非破壊)。
  • concat():配列を結合して新しい配列を返す。slice() は範囲を切り出す。
  • slice() は「部分を取り出す」用途に最適。

7. よくある用途(実用例)

  • 配列の先頭 n 要素だけ取りたい → arr.slice(0, n)
  • 配列の最後の n 要素だけ取りたい → arr.slice(-n)
  • 配列を丸ごとコピーして別操作 → const copy = arr.slice()
  • ページネーション(配列を分割してページ表示) → arr.slice(pageStart, pageEnd)

8. 練習問題(解答・解説付き)

初級

  1. ['a','b','c','d'].slice(1,3) の結果は?
    • 解答:['b','c']
    • 解説:インデックス1〜2を取る(3は含まない)。
  2. [10,20,30].slice() の結果は?
    • 解答:[10,20,30](元と別の配列)

中級

  1. [0,1,2,3,4,5].slice(2,-1) の結果は?
    • 解答:[2,3,4]
    • 解説:開始はインデックス2、終了は末尾の1つ手前(index 5 の手前 → index 4 まで)。
  2. arr = [1,2,3]; b = arr.slice(); b.push(4); console.log(arr) は何が出る?
    • 解答:[1,2,3]
    • 解説:barr のコピーなので b.push は元に影響しない。

上級(参照型の落とし穴)

  1. orig = [{x:1},{x:2}]; sub = orig.slice(0,1); sub[0].x = 9; console.log(orig[0].x) の出力は?
    • 解答:9
    • 解説:浅いコピーのため内部のオブジェクトは同じ参照を指す。

まとめ(初心者が覚えるべき要点)

  • slice()非破壊で配列の一部を取り出す(新しい配列を返す)。
  • slice(start, end)start から end手前 までを取る(end は含まない)。
  • 引数を省略すると「丸ごとコピー」になる。
  • -1 のような負の値は末尾から数える便利な指定。
  • 要素がオブジェクトなら 浅いコピー に注意(内部は同じ参照)。
タイトルとURLをコピーしました