JavaScript

Extracts a portion of an array or string without modifying the original.

slice

slice は、配列や文字列の一部を 切り出して新しい値 を作るメソッドです(元は変わりません)。

このページでできるようになること

最小デモ:まず動かす

配列と文字列で、slice(start, end) を体感します(end は含まれません)。

配列 [0, 1, 2, 3, 4] から slice(1, 4) を実行。

文字列 'JavaScript' から slice(4)slice(-6) を実行。

JavaScript

const nums = [0, 1, 2, 3, 4];
const part = nums.slice(1, 4);   // [1, 2, 3](endは含まない)

const name = 'JavaScript';
const tail1 = name.slice(4);     // 'Script'
const tail2 = name.slice(-6);    // 'Script'(末尾から6文字)

基本の書き方

array.slice(start, end)
配列の startendendは含まない)を shallow copy で返します。
string.slice(start, end)
文字列の部分文字列を返します(文字列は不変なので元は変わりません)。
slice()
配列なら「全体の浅いコピー」、文字列なら「同じ文字列」が返ります。

JavaScript

const a = [1, 2, 3];

const copy = a.slice();      // [1, 2, 3](元は変わらない)
const head2 = a.slice(0, 2); // [1, 2]
const last1 = a.slice(-1);   // [3]

仕様として押さえるポイント(ここで事故を防ぐ)

end は「含まない」

slice(1, 4)1 番目から始まり、4 番目の 手前 までです。

負のインデックスは末尾基準

-1 は末尾要素、-2 は末尾から2番目…という意味になります(配列・文字列どちらも同じ感覚)。

JavaScript

const a = ['a', 'b', 'c', 'd', 'e'];

a.slice(-2);      // ['d', 'e']
a.slice(1, -1);   // ['b', 'c', 'd'](endが負数でもOK)

元を変更しない(非破壊)

slice は元の配列(要素並び)を変えません。破壊的に切り出したいなら splice が別物です。

配列の slice は shallow copy(浅いコピー)

取り出した配列の「要素参照」はコピーされますが、要素がオブジェクトの場合は中身が共有されます。

JavaScript

const items = [{ n: 1 }, { n: 2 }, { n: 3 }];
const part = items.slice(0, 2);

part[0].n = 999;
console.log(items[0].n); // 999(同じオブジェクトを参照している)

splice / substring との違い(混同しやすいところ)

slice(配列/文字列)
非破壊で切り出す。end は含まない。負のインデックスOK。
splice(配列)
配列を 破壊的 に変更して取り除く/挿入する。戻り値は「取り除いた要素の配列」。
substring(文字列)
非破壊で切り出すが、負の値は 0 として扱われ、引数の大小が入れ替わるなど挙動が違う。

JavaScript

const s = 'JavaScript';

s.slice(-6);        // 'Script'
s.substring(-6);    // 'JavaScript'(負の値は0扱い)

実務でよくある使用例(現場で効く)

破壊的メソッドの前にコピーを作る

sort / reverse は配列を破壊します。元を残したいときは slice() を噛ませます。

JavaScript

const scores = [10, 3, 20];

const sorted = scores.slice().sort((a, b) => a - b);
console.log(scores); // [10, 3, 20](元の並びは保持)
console.log(sorted); // [3, 10, 20]

ページング(先頭からn件 / 次のn件)

JavaScript

const items = ['a', 'b', 'c', 'd', 'e', 'f'];

const pageSize = 2;
const page2 = items.slice(pageSize * 1, pageSize * 2); // ['c', 'd']

末尾側だけ取りたい(ログ・履歴の最新n件)

JavaScript

const logs = [/* ... */];
const latest10 = logs.slice(-10);

よくある間違い

試験(JavaScriptプログラミング能力認定試験)で得点できる整理

ひっかけポイント(短く)

ミニ確認(判断する形)

Q1. [1,2,3,4].slice(1,3) の結果は?
A. [2, 3]end は含まない)。
Q2. a.slice() をした後、a.sort() をするとコピーは影響を受ける?
A. 受けません。slice() は新しい配列を返し、sort() は元配列を破壊的に並べ替えます。
Q3. 配列要素がオブジェクトのとき、a.slice() は中身まで完全コピー?
A. いいえ。参照がコピーされるだけで、同じオブジェクトを共有します(shallow copy)。

よくある質問(FAQ)

slicesplice の一番大きい違いは?
slice は非破壊で切り出し、splice は配列を破壊的に変更します。
sliceend はなぜ含まれない?
start から end 手前まで」という半開区間にすると、長さ計算(end - start)が直感的で、範囲を繋げても重複しにくいからです。
slice() で配列をコピーすれば安全?
要素がプリミティブなら多くの場面で安全ですが、要素がオブジェクトなら shallow copy なので中身は共有されます。
文字列は substring とどっちを使う?
負のインデックスを使いたい・配列と同じ感覚で書きたいなら slice が迷いにくいです。

まとめ