JavaScriptのslice()メソッドとは
Array.prototype.slice()は、配列の要素を取り出して新しい配列を作成することができます。
基本的な構文は以下の通りで、2つの引数を取ります。
slice(startIndex, endIndex);
startIndexとendIndexの両パラメータは任意のため、別に引数がなくてもslice()メソッドを使用することは可能です。
- 第1引数のstartIndexは抽出を開始するインデックス番号を渡し、startIndexが未定義の場合、slice()は 0番目の要素から抽出を開始する
- 第2引数のendIndexはその名の通り、抽出を終了するインデックス番号であり、slice()は[endIndex-1]までを抽出する→slice()はendIndex番目の要素を新しい配列に含めない
- endIndexを省略した場合、slice() メソッドは配列のlengthをendIndexに渡す
slice()は、元の配列の要素を含む新しい配列を返します。また、元の配列を変更することはありません。
配列のslice()メソッドの実用的な使い方3選
JavaScriptの配列におけるslice()メソッドの有効的な使い方に以下の3つがあります。
- 配列をクローンする
- 配列の一部をコピーする
- 配列のようなオブジェクトを配列に変換する
それぞれ詳しく解説します。
配列を複製する
slice()は、次の例のように、配列の複製を作成するために使うことができます。
let names = ['Tanaka', 'Aoki', 'Kato']
let cloneNames = names.slice()
console.log(cloneNames) // ['Tanaka', 'Aoki', 'Kato']
slice()メソッドは第1引数と第2引数のどちらも省略された場合、インデックス番号が0番目の要素から[length – 1]番目までの要素が抽出されるため、結果として元の配列の複製を作ることになります。
配列の一部をコピーする
以下のコードは元の配列に手を加えず、配列の一部の要素をコピーする例です。
let names = ['Tanaka', 'Aoki', 'Kato', 'Yamazaki', 'Sawada']
let copyNames = names.slice(0, 3)
console.log(names) // ['Tanaka', 'Aoki', 'Kato', 'Yamazaki', 'Sawada']
console.log(copyNames) // ['Tanaka', 'Aoki', 'Kato']
配列copyNameは配列namesの最初から3つ目までの要素をコピーして新しい配列を作りました。
また、コピー元となった配列namesは要素が抜き取られてる訳ではないため、最初と同じく5つの要素を含んだままとなります。
配列のようなオブジェクトを配列に変換する
slice()メソッドは配列のようなオブジェクトを配列に変換するためにも使うことができます。
function toArray() {
return Array.prototype.slice.call(arguments);
}
let result = toArray('Tanaka','Aoki','Kato');
console.log(result); // ['Tanaka','Aoki','Kato']
この例では、toArray()関数の引数は、配列のようなオブジェクトとなります。toArray()関数の内部では、slice()メソッドを呼び出して、引数オブジェクトを配列に変換しています。
つまり、toArray()関数に渡す全ての引数は、新しい配列の要素になります。
また、よく見かける典型的な例として、以下のようにNodeListを配列に変換することがあります。
let div = document.querySelectorAll('div');
let list = Array.prototype.slice.call(div);
上記の例では、まずdocument.querySelectorAll()を使って、HTML中の全てのdiv要素を取得しています。このメソッドの結果は、配列のようなオブジェクトであるNodeListオブジェクトです。
次に、slice()メソッドを呼び出してNodeListオブジェクトを配列に変換しています。
また、挙動は上記のコードと同じですが、少しスッキリした記述方法として以下の書き方があります。
let list = [].slice.call(document.querySelectorAll('div'));
違いとしましては、空の配列をインスタンス化し、その空の配列を介してslice()を呼び出している点ですね。