【JavaScript】fillメソッドの使い方!配列を一括で変更できます!

この記事ではJavaScriptの『fillメソッド』について、

  • fillメソッドとは
  • fillメソッドの構文
  • fillメソッドの使い方
    • 配列の全ての要素を同じ値で埋める
    • 配列の特定の範囲の要素を同じ値で埋める
    • ある値で埋められている配列を新規作成する
  • fillメソッドの注意点
    • オブジェクトを引数に渡すと参照渡しになる
  • fillメソッドの特徴
    • 配列の長さは変わらない
    • start < -array.lengthまたはstartが省略された場合は0が使用される
    • start >= array.lengthの場合は何も上書きされない
    • end < -array.lengthの場合は 0 が使用される
    • end >= array.lengthまたはendが省略された場合はarray.lengthが使用される
    • endstartと同じかそれより前の場合は何も上書きされない

などをサンプルコードを用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。

fillメソッドとは

fillメソッドは、配列の「全ての要素」や「特定の範囲の要素」を一括変更するメソッドです。要素数が大きい配列に対して、配列を一括変更したい場合や、初期値を設定したい場合などに便利なメソッドです。

後ほどfillメソッドの構文や使い方について詳しく説明しますが、まず以下に示す簡単なサンプルコードを見てみましょう。

const arr = [1, 2, 3, 4, 5];
arr.fill(0);
console.log(arr); // [0, 0, 0, 0, 0]

上記のサンプルコードでは、配列arrの全ての要素を0に変更しています。

fillメソッドの構文

fillメソッドの構文を以下に示します。

fillメソッドの構文

array.fill(value[, start[, end]])

arrayは配列です。fillメソッドの引数と返り値を以下に示します。

引数

  • value
    • 配列を上書きする値です。
  • start(省略可能)
    • 開始位置のインデックスです。
    • このインデックスからvalueで上書きします。
    • 例えば、startに1を指定した場合、配列arrayのインデックス1から上書きを開始します。
  • end(省略可能)
    • 終了位置のインデックスです。
    • このインデックスより前の要素までvalueで上書きします。
    • 例えば、endに4を指定した場合、配列arrayのインデックス3までを上書きします。

返り値(戻り値)

  • valueで上書きされて変更された配列です。

第2引数startと第3引数endを省略した場合、配列の全ての要素を第1引数valueで上書きします。

以下にすべての引数を使用したサンプルコードを示します。

const arr = [1, 2, 3, 4, 5];
arr.fill(0, 1, 4);
console.log(arr); // [1, 0, 0, 0, 5]

上記のサンプルコードでは、valueに0、startに1、endに4を指定することで、配列arrのインデックス1から3までを0で上書きしています。

fillメソッドの使い方

fillメソッドについて、以下に示している使い方をこれから説明します。

  • 配列の全ての要素を同じ値で埋める
  • 配列の特定の範囲の要素を同じ値で埋める
  • ある値で埋められている配列を新規作成する

上記の使い方について順番に説明します。

配列の全ての要素を同じ値で埋める

fillメソッドを使うと、配列の全要素を一括で変更することができます。

以下のサンプルコードでは、配列arrの全ての要素を9で上書きしています。

const arr = [1, 2, 3, 4, 5];
arr.fill(9);
console.log(arr); // [9, 9, 9, 9, 9]

配列の特定の範囲の要素を同じ値で埋める

fillメソッドでは、第2引数startや第3引数endを指定することで、範囲を限定して値を上書きすることができます。

以下のサンプルコードでは、第2引数startに1、第3引数endに4を指定することで、配列arrのインデックス1から3までを0で上書きしています。

const arr = [1, 2, 3, 4, 5];
arr.fill(0, 1, 4);
console.log(arr); // [1, 0, 0, 0, 5]

負のインデックスを用いる場合

第2引数startと第3引数endには負のインデックスを指定することも可能です。

startendに負のインデックスを指定することで、末尾からの位置を基準に範囲を指定することができます。具体的には、start < 0の場合、start + array.lengthが使用されます。同様にend < 0 の場合、end + array.lengthが使用されます。

以下にサンプルコードを示します。

const arr = [1, 2, 3, 4, 5]; // 配列の長さ(arr.length)は5
arr.fill(0, -4, -1); // startは「start + arr.length = 1」, endは「end + arr.length = 4」 になる。
console.log(arr); // [1, 0, 0, 0, 5]

ある値で埋められている配列を新規作成する

Arrayコンストラクタとfillメソッドを組み合わせると、初期化された配列を簡単に作成することができます。

以下のサンプルコードでは、新しい配列arrを作成し、その全ての要素を0で埋めています。

const arr = new Array(5).fill(0); // const arr = new Array(5).fill(0); でも可能
console.log(arr); // [0, 0, 0, 0, 0]

fillメソッドの注意点

fillメソッドを使う上での注意点を以下に示します。

  • オブジェクトを引数に渡すと参照渡しになる

上記の注意点についてプログラム例を用いて説明します。

オブジェクトを引数に渡すと参照渡しになる

fillメソッドの第1引数valueにオブジェクトを渡した場合には注意が必要です。以下にサンプルコードを示します。

const arr = Array(3).fill({ x: 0 });
console.log(arr); // [ { x: 0 }, { x: 0 }, { x: 0 } ]

// fillメソッドで0番目の要素のオブジェクトのxプロパティの値を1にする。
arr[0].x = 1;
console.log(arr); // [ { x: 1 }, { x: 1 }, { x: 1 } ] ← 全ての要素が変更されてしまう!!

上記のサンプルコードからわかるように、配列arrの0番目の要素arr[0]を変更しただけで、他の全ての要素が変更されてしまいます。これは、JavaScriptではオブジェクトが「参照渡し」されるからです。具体的には、3つの要素は全て同じオブジェクト{ x: 0 }を参照しています。そのため、どれか1つの要素を変更すると、他の要素も変更されてしまいます。

上記の問題の解決方法について説明します。

【解決方法1】別オブジェクトで初期化する

mapメソッドを使って、各要素を別のオブジェクトで初期化します。これにより、1つの要素を変更しても他の要素に影響を与えなくなります。以下にサンプルコードを示します。

const arr = Array(3)
  .fill()
  .map(() => ({ x: 0 }));
arr[0].x = 1;
console.log(arr); // [ { x: 1 }, { x: 0 }, { x: 0 } ]

【解決方法2】ループを回して初期化する

ループを使用して各要素を個別のオブジェクトで初期化します。この方法でも「参照渡し」の問題を解決できます。以下にサンプルコードを示します。

const arr = Array(3);
for (let i = 0; i < arr.length; i++) {
  arr[i] = { x: 0 };
}
arr[0].x = 1;
console.log(arr); // [ { x: 1 }, { x: 0 }, { x: 0 } ]

fillメソッドの特徴

fillメソッドの特徴を以下に示します。

  • 配列の長さは変わらない
  • start < -array.lengthまたはstartが省略された場合は0が使用される
  • start >= array.lengthの場合は何も上書きされない
  • end < -array.lengthの場合は0が使用される
  • end >= array.lengthまたはendが省略された場合はarray.lengthが使用される
  • endstartと同じかそれより前の場合は何も上書きされない

各特長について順番に説明します。

配列の長さは変わらない

fillメソッドは配列の長さを変更しません。そのため、新しい要素を追加したり、要素を削除することはできないです。以下にサンプルコードを示します。

const arr = [1, 2, 3];
arr.fill(0, 1, 5);
console.log(arr); // [1, 0, 0]

上記のサンプルコードから分かるように、startを1、endを5に指定しても、配列の長さは変わらず、範囲外のインデックスは無視されます。

start < -array.lengthまたはstartが省略された場合は0が使用される

startが負のインデックスで配列の長さより小さい場合」、または「startが省略された場合」は、startは0として扱われます。以下にサンプルコードを示します。

// start が負の値で、配列の長さより小さい場合
const arr1 = [1, 2, 3, 4, 5];
arr1.fill(0, -6);
console.log(arr1); // [0, 0, 0, 0, 0]

// start が省略された場合
const arr2 = [1, 2, 3, 4, 5];
arr2.fill(0);
console.log(arr2); // [0, 0, 0, 0, 0]

arr1の例では、startに-6を指定しており、これは配列の長さ(-arr1.length = -5)より小さいです。そのため、startは0として扱われ、配列全体が0で上書きされます。

arr2の例では、startを省略しています。そのため、startは0として扱われ、配列全体が0で上書きされます。

start >= array.lengthの場合は何も上書きされない

startが配列の長さ以上の場合は、配列を何も上書きしません。以下にサンプルコードを示します。

const arr = [1, 2, 3, 4, 5];
arr.fill(0, 5);
console.log(arr); // [1, 2, 3, 4, 5]

startに5を指定していますが、これは配列の長さ(arr.length = 5)と同じです。そのため、配列arrを何も上書きしません。

end < -array.lengthの場合は0が使用される

endが負の値で配列の長さより小さい場合は、endは0として扱われます。以下にサンプルコードを示します。

const arr = [1, 2, 3, 4, 5];
arr.fill(0, 1, -6);
console.log(arr); // [ 1, 2, 3, 4, 5 ]

endに-6を指定しており、これは配列の長さ(-arr.length = -5)より小さいです。そのため、endは0として扱われます。なお、endstartより前になるので、配列arrを何も上書きしません。

end >= array.lengthまたはendが省略された場合はarray.lengthが使用される

endが配列の長さ以上の場合」、または「endが省略された場合」は、endarray.lengthとして扱われます。以下にサンプルコードを示します。

const arr1 = [1, 2, 3, 4, 5];
arr1.fill(0, 1, 10);
console.log(arr1); // [1, 0, 0, 0, 0]

const arr2 = [1, 2, 3, 4, 5];
arr2.fill(0, 1);
console.log(arr2); // [1, 0, 0, 0, 0]

arr1の例では、endに10を指定しており、これは配列の長さ(arr.length = 5)より大きいです。そのため、endは配列の長さ(arr.length = 5)として扱われ、配列の最後まで上書きされます。

arr2の例では、endを省略しています。そのため、endは配列の長さ(arr.length = 5)として扱われ、配列の最後まで上書きされます。

endがstartと同じかそれより前の場合は何も上書きされない

endstartと同じかそれより前の場合、配列を何も上書きしません。以下にサンプルコードを示します。

const arr1 = [1, 2, 3, 4, 5];
arr1.fill(0, 2, 2);
console.log(arr1); // [1, 2, 3, 4, 5]

const arr2 = [1, 2, 3, 4, 5];
arr2.fill(0, 3, 2);
console.log(arr2); // [1, 2, 3, 4, 5]

上記のサンプルコードでは、endstartと同じ、またはstartより前なので、配列を何も上書きしません。

本記事のまとめ

この記事ではJavaScriptの『fillメソッド』について、以下の内容を説明しました。

  • fillメソッドとは
  • fillメソッドの構文
  • fillメソッドの使い方
    • 配列の全ての要素を同じ値で埋める
    • 配列の特定の範囲の要素を同じ値で埋める
    • ある値で埋められている配列を新規作成する
  • fillメソッドの注意点
    • オブジェクトを引数に渡すと参照渡しになる
  • fillメソッドの特徴
    • 配列の長さは変わらない
    • start < -array.lengthまたはstartが省略された場合は0が使用される
    • start >= array.lengthの場合は何も上書きされない
    • end < -array.lengthの場合は 0 が使用される
    • end >= array.lengthまたはendが省略された場合はarray.lengthが使用される
    • endstartと同じかそれより前の場合は何も上書きされない

お読み頂きありがとうございました。