Array.prototype.copyWithin()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.

copyWithin()Array インスタンスのメソッドで、この配列の一部を配列内の他の場所にシャローコピーし、この配列を長さを変更せずに返します。

試してみましょう

構文

js
copyWithin(target, start)
copyWithin(target, start, end)

引数

target

並びのコピー先となる 0 から始まるインデックスで、整数に変換されます。これは start にある要素がコピーされる場所に対応し、start から end までのすべての要素が後続のインデックスにコピーされます。

  • 負のインデックスの場合は、配列の末尾から逆に数えます。 target < 0 の場合は、 target + array.length が使用されます。
  • target < -array.length の場合は、 0 が使用されます。
  • target >= array.length の場合は、何もコピーされません。
  • target が正規化後の start の後に位置している場合、コピーは array.length の末尾までしか行われません(言い換えれば、 copyWithin() は配列を拡張しません)。
start

要素のコピー元の始まりを表す 0 から始まるインデックスで、整数に変換されます

  • 負のインデックスの場合は、配列の末尾から逆に数えます。 start < 0 の場合は、 start + array.length が使用されます。
  • start < -array.length の場合は、 0 が使用されます。
  • start >= array.length の場合は、何もコピーされません。
end 省略可

要素のコピー元の末尾を表す 0 から始まるインデックスで、整数に変換されますcopyWithin() のコピーは end の手前まで行います。

  • 負のインデックスの場合は、配列の末尾から逆に数えます。 end < 0 の場合は、 end + array.length が使用されます。
  • end < -array.length の場合は、 0 が使用されます。
  • end >= array.length の場合、または end が省略された場合は、 array.length が使用され、末尾までのすべての要素がコピーされます。
  • 正規化後に endstart よりも前か同じ位置になったときは、何もコピーされません。

返値

変更された配列です。

解説

copyWithin() メソッドは C や C++ の memmove のような動きをし、 Array のデータを移動するための高いパフォーマンスのメソッドです。これは特に TypedArray の同名メソッドに当てはまります。データの並びがコピーされ貼り付けられる処理が一命令で行われます。コピー元と貼り付け先で領域が重なっていたとしても、貼り付け先の並びはコピーされた値になります。

undefined は整数に変換されると 0 になるため、 start 引数を省略すると 0 を渡したのと同じ効果があり、配列全体が対象とする位置にコピーされます(右の境界が切り取られ、左の境界が複製される右シフトと同じです)。この動作はコードの読み手を混乱させる可能性があるので、代わりに start として 0 を明示的に渡してください。

js
console.log([1, 2, 3, 4, 5].copyWithin(2));
// [1, 2, 1, 2, 3]; すべての要素を右に 2 つずらす

copyWithin()変更を行うメソッドです。 this の長さは変更しませんが、 this の内容を変更し、必要に応じて新しいプロパティを作成します。

copyWithin() メソッドは空のスロットを保持します。コピー元の範囲が疎配列であった場合、空のスロットに対応するインデックスは削除され、空のスロットになります。

copyWithin() メソッドは汎用的です。このメソッドは this の値に length プロパティと整数のキーを持ったプロパティがあることだけを求めます。文字列も配列風オブジェクトですが、文字列は不変なので、このメソッドを適用するのは適していません。

copyWithin() の使用

js
console.log([1, 2, 3, 4, 5].copyWithin(0, 3));
// [4, 5, 3, 4, 5]

console.log([1, 2, 3, 4, 5].copyWithin(0, 3, 4));
// [4, 2, 3, 4, 5]

console.log([1, 2, 3, 4, 5].copyWithin(-2, -3, -1));
// [1, 2, 3, 3, 4]

疎配列に対する copyWithin() の使用

copyWithin() は空のスロットを広めます。

js
console.log([1, , 3].copyWithin(2, 1, 2)); // [1, empty, empty]

配列ではないオブジェクトに対する copyWithin() の呼び出し

copyWithin() メソッドは thislength プロパティを読み込んで、関係する整数のインデックスを操作します。

js
const arrayLike = {
  length: 5,
  3: 1,
};
console.log(Array.prototype.copyWithin.call(arrayLike, 0, 3));
// { '0': 1, '3': 1, length: 5 }
console.log(Array.prototype.copyWithin.call(arrayLike, 3, 1));
// { '0': 1, length: 5 }
// コピー元が空のスロットであるため、 '3' プロパティは削除される

仕様書

Specification
ECMAScript Language Specification
# sec-array.prototype.copywithin

ブラウザーの互換性

BCD tables only load in the browser

関連情報