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
インスタンスのメソッドで、この配列の一部を配列内の他の場所にシャローコピーし、この配列を長さを変更せずに返します。
試してみましょう
構文
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
が使用され、末尾までのすべての要素がコピーされます。- 正規化後に
end
がstart
よりも前か同じ位置になったときは、何もコピーされません。
- 負のインデックスの場合は、配列の末尾から逆に数えます。
返値
変更された配列です。
解説
copyWithin()
メソッドは C や C++ の memmove
のような動きをし、 Array
のデータを移動するための高いパフォーマンスのメソッドです。これは特に TypedArray
の同名メソッドに当てはまります。データの並びがコピーされ貼り付けられる処理が一命令で行われます。コピー元と貼り付け先で領域が重なっていたとしても、貼り付け先の並びはコピーされた値になります。
undefined
は整数に変換されると 0
になるため、 start
引数を省略すると 0
を渡したのと同じ効果があり、配列全体が対象とする位置にコピーされます(右の境界が切り取られ、左の境界が複製される右シフトと同じです)。この動作はコードの読み手を混乱させる可能性があるので、代わりに start
として 0
を明示的に渡してください。
console.log([1, 2, 3, 4, 5].copyWithin(2));
// [1, 2, 1, 2, 3]; すべての要素を右に 2 つずらす
copyWithin()
は変更を行うメソッドです。 this
の長さは変更しませんが、 this
の内容を変更し、必要に応じて新しいプロパティを作成します。
copyWithin()
メソッドは空のスロットを保持します。コピー元の範囲が疎配列であった場合、空のスロットに対応するインデックスは削除され、空のスロットになります。
copyWithin()
メソッドは汎用的です。このメソッドは this
の値に length
プロパティと整数のキーを持ったプロパティがあることだけを求めます。文字列も配列風オブジェクトですが、文字列は不変なので、このメソッドを適用するのは適していません。
例
copyWithin() の使用
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()
は空のスロットを広めます。
console.log([1, , 3].copyWithin(2, 1, 2)); // [1, empty, empty]
配列ではないオブジェクトに対する copyWithin() の呼び出し
copyWithin()
メソッドは this
の length
プロパティを読み込んで、関係する整数のインデックスを操作します。
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