Array.prototype.copyWithin()
A low-level memmove for arrays, borrowed from the typed-array world. It exists for performance on numeric buffers, and it is almost never the right tool for ordinary application code.
Demo
Watch the LENGTH across every case: it never moves. The first case reads from index 3 to the end and writes that block at index 0, giving [4, 5, 3, 4, 5] — the tail is now duplicated, because the elements it overwrote are simply gone while the ones past the write are left alone. The third case pulls everything up by one and leaves a duplicate of the last element hanging off the end, which is the single most surprising thing about this method: it does not shrink the array the way shift would.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| target | number | yes | Where to start writing. Negative counts from the end. Copying stops when the end of the array is reached. |
| start | number | no (0) | Where to start reading. Negative counts from the end. |
| end | number | no (length) | Where to stop reading, exclusive. Negative counts from the end. |
Return value
Array — The SAME array, modified in place. The length is never changed — elements are overwritten, never inserted or removed.
Common patterns
buf.copyWithin(0, consumed); writePos -= consumed;
frame.copyWithin(half, 0, half);
const moved = [...items.slice(3), ...items.slice(0, 3)];
Examples
Pitfalls
[1, 2, 3].copyWithin(0, 1)
[1, 2, 3].slice(1)
const next = items.copyWithin(0, 1); next === items
const next = [...items].copyWithin(0, 1);
[1, 2, 3].copyWithin(2, 0)
const n = Math.min(count, arr.length - target);
items.copyWithin(0, 1)
items.splice(0, 1)
When to use
- Sliding data down a fixed-size buffer without allocating
- Typed arrays, where this is the idiomatic block move
- Duplicating a range inside a large array in a hot loop
- You want to REMOVE elements → splice, or slice for a copy
- You want a reordered copy → toSpliced, or a spread of two slices
- You want to fill a range with one value → fill
- Ordinary application code → almost anything else reads better
Notes
FAQ
Because copyWithin only overwrites. It reads a block and writes it somewhere else in the same array, and every position it did not write keeps whatever it already held. The length is fixed by definition, which is what makes it safe to use on typed arrays.
[1, 2, 3].copyWithin(0, 1); // [2, 3, 3] — the trailing 3 is the old one