Extracts a portion of an array or string without modifying the original.
slice は、配列や文字列の一部を 切り出して新しい値 を作るメソッドです(元は変わりません)。
start/end の指定で、欲しい範囲だけ切り出せる(end は含まない)slice() で「元を壊さないコピー」を作り、破壊的メソッドの前処理に使えるsplice(元を変える)や substring(文字列専用)と混同せずに使い分けられる配列と文字列で、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)start 〜 end(endは含まない)を 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]
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 が別物です。
取り出した配列の「要素参照」はコピーされますが、要素がオブジェクトの場合は中身が共有されます。
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(同じオブジェクトを参照している)
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]
JavaScript
const items = ['a', 'b', 'c', 'd', 'e', 'f'];
const pageSize = 2;
const page2 = items.slice(pageSize * 1, pageSize * 2); // ['c', 'd']
JavaScript
const logs = [/* ... */];
const latest10 = logs.slice(-10);
end を「含む」と勘違いして1つ多い/少ない(境界は end 手前)slice() を deep copy だと思い、オブジェクト要素の変更で元が変わって驚く(shallow copy)splice と混同して「元が消えない/消える」を取り違える(slice は非破壊)substring と混ぜて、負数の挙動が違って詰まる(負数なら slice が直感的)slice は元の配列を変更する → ×(変更しない。変更するのは splice)slice(1, 3) は 1〜3番目を取り出す → ×(3番目は含まない。実際は 1〜2番目)slice(-1) は先頭から1つ取り出す → ×(末尾から1つ)slice() は deep copy である → ×(浅いコピー)[1,2,3,4].slice(1,3) の結果は?[2, 3](end は含まない)。a.slice() をした後、a.sort() をするとコピーは影響を受ける?slice() は新しい配列を返し、sort() は元配列を破壊的に並べ替えます。a.slice() は中身まで完全コピー?slice と splice の一番大きい違いは?slice は非破壊で切り出し、splice は配列を破壊的に変更します。slice の end はなぜ含まれない?start から end 手前まで」という半開区間にすると、長さ計算(end - start)が直感的で、範囲を繋げても重複しにくいからです。slice() で配列をコピーすれば安全?substring とどっちを使う?slice が迷いにくいです。slice(start, end) は「切り出して新しい値」:元は変わらないend は含まない/負のインデックスは末尾基準slice() は浅いコピー:オブジェクト要素は共有されるsplice(別物)