JavaScriptのArrayオブジェクトは生き物である。知らないうちにメソッドが増えている。理解を深めるためにチートシートをまとめたい。

用語の整理

ドキュメントを読むうえで押さえておきたい、JavaScriptの配列周りの用語をかんたんに整理する。

用語 概要
シャローコピー トップレベルの値のみを対象としたコピー。それより深い参照はそのまま引き継がれる。
コピィングメソッド 配列をコピーしてそれを処理して返すメソッド。
ミューテーティングメソッド 配列を直接変更するメソッド。
イテラブルオブジェクト for...ofループなどを使用して、その要素を一つずつ反復処理できるオブジェクト。JavaScriptでは、ArrayMapSetなどが該当する。
Array-likeオブジェクト 配列とは違うが、インデックスとlengthプロパティを持つオブジェクト。配列のように扱えるが、配列のメソッドは使えない。NodeListHTMLCollectionなどが該当する。
疎配列(Sparse array) [0,,2]のように、空文字でもundefinedでもない値が入った配列。この配列をs[1]のように参照するとundefinedが返るが、実際には何も存在しない。Arrayオブジェクトのメソッドは、疎の値を無視する(ただしlengthなどではカウントされる)。
密配列(Dense array) [0,undefined,2]のように、すべてのインデックスに値が入っている配列。

元の配列を変更するメソッドとその代替

Arrayオブジェクトのメソッドを使う際、それが破壊的なものか非破壊的なものかすぐに忘れる。MDNにわかりよい一覧があったのでパクってみる。

元の配列を変更するメソッド 代替メソッド
copyWithin() ない。のでconst newArray = [...originalArray];とかでコピーしてそれを使う。
fill() 同上。
pop() slice(0, -1)(最後の1つを取得したい場合はslice(-1)
push(v1, v2) concat([v1, v2])
reverse() toReversed()
shift() slice(0)
sort() toSorted()
splice() toSpliced()
unshift(v1, v2) toSpliced(0, 0, v1, v2)

参考(というかほぼ引用):Copying methods and mutating methods

静的メソッド

Array.from(arrayLike, mapFn, thisArg)

Array.from(arrayLike, mapFn, thisArg)は、最多で3つの引数を受け取り、イテラブルオブジェクト、あるいは配列ライクなオブジェクトから新しい配列を作って返す。

2つ目以降の引数はオプション。2つ目の引数には、各要素に適用する関数を渡せる。この関数は、配列の要素とインデックスを引数に受け取る。また、3つ目の引数で、関数内で使うthisの値を指定できる。

Array.fromAsync(arrayLike, mapFn, thisArg)

Array.fromAsync(arrayLike, mapFn, thisArg)は、最多で3つの引数を受け取り、非同期のイテラブルオブジェクト、あるいは配列ライクなオブジェクトから新しい配列を作って返す。

Array.isArray(value)

Array.isArray(value)は、引数を1つ受け取り、それが配列ならtrue、違えばfalseを返す。

Array.of(element1,…,elementN)

Array.of(element1,…,elementN)は、不特定多数の引数を受け取り、配列を作って返す。

インスタンスメソッド

配列.at(index)

配列.at(index)は、引数を1つ受け取り、そのインデックスに該当する要素を返す。インデックスには負数も指定できる。

配列.concat(value1,…,valueN)

配列.concat(value1,…,valueN)は、複数の配列、あるいは値を受け取り、それをつなげた新しい配列を返す。

配列.copyWithin(target,start,end)

配列.copyWithin()は、2つ、または3つの引数を受け取り、1つ目の引数のインデックスにある要素を起点に、2つ目から3つ目の1つ前までのインデックスにある要素と置き換える。

また、2つ目の引数を省略すると0、3つ目の引数を省略すると配列の長さが指定されたと解釈する。

我ながら何がなんだかわからねぇ。以下みたいな感じ。

js
console.log(["a", "b", "c", "d"].copyWithin(0, 2, 3));
//["c", "b", "c", "d"] 👈 2にあった"c"が、0の"a"を上書きした
console.log(["a", "b", "c", "d"].copyWithin(0, 2));
//["c", "d", "c", "d"] 👈 2以降("c"以降)が、"a"以降を上書きした

正直使いどころがよくわからないが、配列全体をシフトしたいときに使うようだ。

配列.entries()

配列.entries()は、何も受け取らず、配列の各インデックスのキーと値のペアを含む新しい配列イテレータオブジェクトを返す。

配列.every(callbackFn, thisArg)

配列.every(callbackFn, thisArg)は、真偽値を返す関数を受け取り、その関数に対して配列がすべて真ならtrue、そうでなければfalseを返す。

配列.fill(value,start,end)

配列.fill(value,start,end)は、最大3つの引数を受け取り、1つ目の引数の値で2つ目から3つ目に渡されたインデックスの範囲を埋める。

また、2つ目の引数を省略すると0、3つ目の引数を省略すると配列の長さが指定されたと解釈する。

js
console.log(["a", "b", "c", "d"].fill(0, 1, 2));
//["a", 0, "c", "d"]
console.log(["a", "b", "c", "d"].fill(0, 1));
//["a", 0, 0, 0]
console.log(["a", "b", "c", "d"].fill(0));
//[0, 0, 0, 0]

配列.filter(callbackFn, thisArg)

配列.filter(callbackFn, thisArg)は、真偽値を返すコールバック関数を受け取り、そのコールバックが真の値を返す要素のみの配列を新たに作って返す(配列はシャローコピー)。1つもない場合は空の配列が返る。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.find(callbackFn, thisArg)

配列.find(callbackFn, thisArg)は、真偽値を返すコールバック関数を受け取り、そのコールバックが真の値を返した最初の要素を返す。何も見つからない場合はundefinedが返る。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.findIndex(callbackFn, thisArg)

配列.findIndex(callbackFn, thisArg)は、真偽値を返すコールバック関数を受け取り、そのコールバックが真の値を返した最初の要素のインデックスを返す。何も見つからない場合は-1が返る。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.findLast(callbackFn, thisArg)

配列.findLast(callbackFn, thisArg)は、真偽値を返すコールバック関数を受け取り、逆順に配列を走査してそのコールバックが真の値を返した最初の要素を返す。何も見つからない場合はundefinedが返る。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.findLastIndex()

配列.findLastIndex()は、真偽値を返すコールバック関数を受け取り、逆順に配列を走査してそのコールバックが真の値を返した最初の要素のインデックスを返す。何も見つからない場合は-1が返る。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.flat(depth)

配列.flat(depth)は、引数を1つ受け取り、その深さまでのサブ配列を平らにならした新たな配列を返す。

引数は省略できる。その場合のデフォルト値は1

配列.flatMap(callbackFn, thisArg)

配列.flatMap(callbackFn, thisArg)は、指定されたコールバック関数を配列の各要素に適用し、その結果を1階層平坦化した新しい配列を返す。

map().flat()と同じだが、少し効率的。らしい。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.forEach(callbackFn, thisArg)

配列.forEach(callbackFn, thisArg)は、配列のそれぞれの要素に対して、渡されたコールバック関数を呼び出す。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.includes(searchElement, fromIndex)

配列.includes(searchElement, fromIndex)は、受け取った引数を配列が含む場合はtrue、含まない場合はfalseを返す。

2つ目の引数で、検索を開始するインデックスを指定できる。

配列.indexOf(searchElement, fromIndex)

配列.indexOf(searchElement, fromIndex)は、受け取った引数が最初に見つかったインデックスを返す。

2つ目の引数で、検索を開始するインデックスを指定できる。

配列.join(sepalator)

配列.join(sepalator)は、配列のすべての要素を1つの文字列に結合する。

引数に文字列を渡すと、各要素の間にその文字列を挿入する。引数を省略すると、カンマ区切りとなる。そのまま結合したいときは""を指定する。

配列.keys()

配列.keys()は、配列の各インデックスのキーを含む新しい配列イテレータオブジェクトを返す。

疎配列のキーを効率的に取り出せる。

配列.lastIndexOf(searchElement, fromIndex)

配列.lastIndexOf(searchElement, fromIndex)は、受け取った引数が最後に見つかったインデックスを返す。

2つ目の引数で、検索を開始するインデックスを指定できる。

配列.map(callbackFn, thisArg)

配列.map(callbackFn, thisArg)は、渡されたコールバック関数を各要素に適用し、新たな配列を返す。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.pop()

配列.pop()は、配列から最後の要素を取り除き、その要素を返す。

配列.push(element1,…,elementN)

配列.push()は、1つ以上の値を配列の末尾に追加したうえで、追加後の配列の長さを返す。

配列が返されない点に注意。

配列.reduce(callbackFn, initialValue)

配列.reduce(callbackFn, initialValue)は、コールバック関数を受け取り、そのコールバック関数で各要素を累算して、1つの値にまとめて返す。

累算なんて、意味もわからず使ってしまった。

reduce()メソッドの1つ目の引数として渡すコールバックは、リデューサとも呼ばれる。リデューサは以下の4つの引数を受け取る。

  • accumulator…"-tor"とあるとすごそうだが、各要素に関数を適用し、合体させてきたただの値である。
  • currentValue…現在の要素の値
  • currentIndex…現在の要素のインデックス
  • array…元の配列

また、reduce()メソッドの2つ目の引数で、累積する際の初期値を指定できる。

js
console.log(
  ["r", "e", "d", "u", "c", "e", "r!"].reduce((a, c) => a + c, "Hello, ")
);
//"Hello, reducer!"

配列.reduceRight(callbackFn, initialValue)

配列.reduceRight(callbackFn, initialValue)は、逆順にしたreducer()メソッド。なので省略。

配列.reverse()

配列.reverse()は、逆順にした配列を返す。

配列.toReversed()

配列.toReversed()は、逆順にした新たな配列を返す。

配列.shift()

配列.shift()は、最初の要素を取り除き、その要素を返す。

配列.slice(start, end)

配列.slice(start, end)は、渡された引数に応じて元の配列から要素を新たな配列を切り出して返す。

また、2つ目の引数を省略すると配列の長さが指定されたと解釈する。

js
console.log([0, 1, 2].slice(0, 0));
//[]
console.log([0, 1, 2].slice(0, 1));
//[0]
console.log([0, 1, 2].slice(0, 2));
//[0, 1]
console.log([0, 1, 2].slice(0));
//[0, 1, 2]
console.log([0, 1, 2].slice(2));
//[2]

配列.some(callbackFn, thisArg)

配列.some(callbackFn, thisArg)は、渡されたコールバック関数が、少なくとも1つ真を返す場合にtrueを返す。

コールバックが受け取る引数は、要素、インデックス、元の配列の3つ。

配列.sort(compareFn)

配列.sort(compareFn)は、渡された関数に基づいてソートした配列を返す。

微妙にややこしいので、比較関数については別ページにまとめた。

デフォルトではUTF-16の文字コードに基づいてソートが行われる。

配列.toSorted(compareFn)

配列.toSorted(compareFn)は、ソートした新たな配列を返す。

ソートに使う関数の詳細は別ページ参照。

配列.splice(start, deleteCount, item1, item2,…, itemN)

配列.splice(start, deleteCount, item1, item2,…, itemN)は、引数に渡された値に基づき、要素を削除したり追加したりする。返り値は、削除された値の配列。

ちなみに"splice"は、"接合"とか"継ぐ"とか、そんな感じの英単語である。

1つ目の引数で変更の起点となるインデックスを指定する。2つ目の引数で、削除する要素の数を指定する。削除しない場合は0を渡す。

3つ目以降は、配列に追加する要素の値を指定する。

js
const sampleArray = ["s", "p", "l", "i", "c", "e"];
console.log(sampleArray.splice(0, 3, "p", "e", "a", "r", "l", "r"));
//["s", "p", "l"]
console.log(sampleArray);
//["p", "e", "a", "r", "l", "r", "i", "c", "e"]

配列.toSpliced(start, deleteCount, item1, item2,…, itemN)

配列.toSpliced(start, deleteCount, item1, item2,…, itemN)は、配列.splice()の元配列を変えない版。返り値は削除した値ではなく、変更を施した新たな配列。

配列.toLocaleString(locales, options)

配列.toLocaleString(locales, options)は、与えられた値に基づいて各値をローカライズし、1つの文字列にして返す。ローカライズできない場合、値はそのまま文字列にされる。

1つ目の引数のlocalesは、BCP 47の言語タグを持つ文字列、またはそのような文字列の配列。

2つ目のoptionsは、設定用のオブジェクト。数値の設定はNumber.prototype.toLocaleString()、日付の設定はDate.prototype.toLocaleString()にある。らしい。

正直、両方とも馴染みがないのでよくわからない。

js
console.log(
  [1, "a", 5, 10, 50, 100, 500].toLocaleString("ja-JP", {
    style: "currency",
    currency: "JPY",
  })
);
//"¥1,a,¥5,¥10,¥50,¥100,¥500"
console.log(
  [1, "a", new Date("21 Dec 1997 14:12:00 UTC")].toLocaleString("en", {
    timeZone: "UTC",
  })
);
//"1,a,12/21/1997, 2:12:00 PM"

配列.toString()

配列.toString()は、配列の要素をカンマ区切りの1つの文字列にして返す。

配列.unshift(element1, …, elementN)

配列.unshift(element1, …, elementN)は、1つ以上の要素を配列の先頭に追加し、新しい配列の長さを返す。

複数の値を引数に渡す場合、渡す順番に挿入される。そのため、n個の引数をまとめて渡す場合と、メソッドをn回呼び出す場合とでは、結果が変わる。

js
const sample1 = [];
sample1.unshift("r", "a", "t", "s");
console.log(sample1);
//["r", "a", "t", "s"]
sample2 = [];
sample2.unshift("r");
sample2.unshift("a");
sample2.unshift("t");
sample2.unshift("s");
console.log(sample2);
//["s", "t", "a", "r"]

配列.values()

配列.values()は、配列の各項目の値を反復処理する新しい配列イテレータ・オブジェクトを返す。

配列.with(index, value)

配列.with(index, value)は、インデックスと値を受け取り、該当するインデックスの値を渡された値に置き換えた新しい配列を返す。

配列[@@iterator]()

配列[@@iterator]()は、配列の各インデックスの値を返す配列イテレータオブジェクトを返す。

参考資料