The JavaScript Array copyWithin method is a built-in method that allows us to copy a sequence of elements within an array to another location within the same array, overwriting any existing elements. In this tutorial, let us learn more about the copyWithin method.
Table of Contents
copyWithin
The copyWithin method is a built-in method that allows us to copy a sequence of elements within an array to another location within the same array, overwriting any existing elements.
copyWithin does not change the length of the array. It copies the elements until the end of the array.length
. It will discard anything beyond the array.length
.
The copyWithin method preserves empty slots.
copyWithin does a shallow copy. If any nested objects or arrays are present in the array, it will copy their references.
copyWithin is a generic method. It will also work on array-like objects.
Syntax
The syntax for the copyWithin method is as follows.
1 2 3 | Array.copyWithin(target, start, end) |
Where the target is the index of the element to copy the sequence to, the start is the index of the first element to copy from, and the end is the index of the last element to copy from (but not including).
Parameters
target
The target
is the starting index of the element to copy the sequence to
If the target
is a negative integer, the index counts backward from the array’s end. i.e., if target < 0
, then the target + array.length
is used.
And if the target
is a negative integer and is less than -array.length
, then it will default to 0.
copyWithin
will not copy anything if the target
is greater than the array.length
.
start
The start
is the index of the first element to copy from
The start
is optional, and if omitted, then it will default to 0.
The index counts backward from the array’s end if the start
is negative, i.e., if start < 0
, then the start + array.length
is used.
And if the start
is negative and < -array.length
, then 0 is used.
If the start
is greater than the array.length
nothing is copied
end
The end
is the index of the last element to copy from (but not including the end).
The end
is optional, and if omitted, then it will default to array.length
.
The index counts backward from the array’s end if the end is negative .i.e., if end < 0
, then the end + array.length
is used.
If the end
is negative and < -array.length
, then it defaults to 0
.
If the end
is greater than an array.length
, then it defaults to array.length
.
Examples of copyWithin
Copying Single element
In this example, we start with an array [1, 2, 3, 4, 5]
, and we want to copy the item from index 0 (Value 1) to index 3 (Value 4).
Since we want to copy to location 3, it becomes our target
.
The value for the start
argument is the index number from where we want to copy. Since we want to copy the value from index 0, it becomes our start
.
The 1 is the value of the end
argument, which is the following index after the start index, so we only copy one element.
Hence, we invoke the copyWithin(3,0,1)
.
1 2 3 4 5 6 7 8 9 10 11 12 | let numArr = [1, 2, 3, 4, 5]; // target=3 start =0 end = 1 // copies element from index 0 to index 3 numArr.copyWithin(3, 0,1); console.log(numArr); //output //[ 1, 2, 3, 1, 5 ] // Value 1 from index 0 is now copied to index 3 |
Copying Multiple elements
In this example, we start with an array [1, 2, 3, 4, 5]
, and we want to copy the sequence of items from index 0 to 1 (2 elements) to index 3 & 4.
Hence, we invoke the copyWithin(3, 0,2)
.
Here 2 is the target
, and 0 is the index of the first element. The 2 is the value of the end
argument, which is the following index after the end of the sequence, so we copy two elements in total.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | let numArr = [1, 2, 3, 4, 5]; // target=3 start =0 end = 2 // Copies 2 element from index 0 & 1 to index 3 & 4 numArr.copyWithin(3, 0,2); console.log(numArr); //output //[ 1, 2, 3, 1, 2 ] // Value 1 from index 0 is now copied to index 3 // Value 2 from index 1 is now copied to index 4 // Values at target locations are overwritten |
The code below copies three elements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | let numArr = [1, 2, 3, 4, 5, 6, 7]; // target=3 start =0 end = 3 // Copies 2 element from index 0 to 2 to index 3 to 5 numArr.copyWithin(3,0,3); console.log(numArr); //output //[ 1, 2, 3, 1, 2, 3, 7 ] // Value 1 from index 0 is now copied to index 3 // Value 2 from index 1 is now copied to index 4 // Value 2 from index 2 is now copied to index 5 // Values at target locations are overwritten |
Copying elements beyond array.length
The code below copies three elements at target
Index 3. But the last index of the array is 4. Hence it will copy only two elements and discards the others.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | let numArr = [1, 2, 3, 4, 5]; // target=3 start =0 end = 3 // copies element from index 0 to 2 to index 3 (i.e. 3 to 5) numArr.copyWithin(3,0,3); console.log(numArr); //output //[ 1, 2, 3, 1, 2 ] // Value 1 from index 0 is now copied to index 3 // Value 2 from index 1 is now copied to index 4 // Value 3 from index 2 is not copied because there is index 5 does not exists in array. |
When the target is a -ve integer
If the target
is a negative integer, the index counts backward from the array’s end. i.e., if target
< 0, then the target + array.length
is used.
For example, -2 is the target and 5 is the array length. Then the target is treated as 3 (-2 + 5 ) . Hence copyWithin(-2,0,2)
is same as copyWithin(3,0,2)
1 2 3 4 5 6 7 8 9 10 11 | let numArr = [1, 2, 3, 4, 5]; numArr.copyWithin(-2,0,2); //numArr.copyWithin(3,0,2); console.log(numArr); //output //[ 1, 2, 3, 1, 2 ] |
If the target
is a negative integer and is less than -array.length
, then it will default to 0.
In the code below the target
is -5. then target + array.length
is 0. If target
is less than -5 then target + array.length
becomes -ve integer. In these conditions the target
defaults to 0.
Hence copyWithin(-5,2,3)
, copyWithin(-6,2,3)
, copyWithin(-9,2,3)
, etc. are same as copyWithin(0,2,3)
.
1 2 3 4 5 6 7 8 9 10 | let numArr = [1, 2, 3, 4, 5]; numArr.copyWithin(-5,2,3); //numArr.copyWithin(0,2,3); console.log(numArr); //output //[ 1, 2, 3, 1, 2 ] |
When the start & end is a -ve integer
Similarly, when both the start
and the end
are -ve, add the array.length
to arrive at the correct number.
The example below shows the start
and end
are -3 and -2. Add array.length
, which is 5 to both. Hence copyWithin(0,-3,-2)
is same as copyWithin(0,2,3)
1 2 3 4 5 6 7 8 9 10 | let numArr = [1, 2, 3, 4, 5]; numArr.copyWithin(0,-3,-2); //numArr.copyWithin(0,2,3); console.log(numArr); //output //[ 1, 2, 3, 1, 2 ] |
Shallow Copy
The copyWithin does a shallow copy of the elements. i.e., objects and arrays within the elements are not deeply copied.
For example, the following array contains an object at index 1. We copy it to location 3. Because it is a shallow copy, both point to the same object. If we modify any of them, it will also affect the other because they are references to the same object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | obj = { foo:'foo', boo:'boo' } let arr = ["Apples",obj,1,2 ]; console.log(arr) arr.copyWithin(3,1,2); console.log(arr); //[ 'Apples', { foo: 'foo', boo: 'boo' }, 1, { foo: 'foo', boo: 'boo' } ] obj.foo="boo" obj.boo="foo" console.log(arr); //'Apples', { foo: 'boo', boo: 'foo' }, 1, { foo: 'boo', boo: 'foo' } ] |
copyWithin preserves empty slots
copyWithin preserves the empty slots (sparse arrays). i.e., it will copy the empty slots to the target location.
1 2 3 4 5 6 7 8 9 10 11 12 | let numArr = [1, , 3, 4, 5]; //Empty element at index 1 console.log(numArr); //[ 1, <1 empty item>, 3, 4, 5 ] numArr.copyWithin(3,0,2); console.log(numArr); //Empty element is copied to index 4 //[ 1, <1 empty item>, 3, 1, <1 empty item> ] |
Array-like objects and copyWithin
copyWithin is a generic function. We can use it call any array like objects. But to do that we need to use the call
method
In the example below, arrLike
is an object, but has a structure that is similar to array. Since it is not an array, we cannot invoke arrLike.copyWithin
. But we can invoke the copyWithin
using the call
method.
1 2 3 4 5 6 7 8 9 10 11 | const arrLike = { 0:"apple", 1:"orange", 2:"banana", length:3} console.log(arrLike); //{ '0': 'apple', '1': 'orange', '2': 'banana', length: 3 } Array.prototype.copyWithin.call(arrLike,2,0,1) console.log(arrLike); //{ '0': 'apple', '1': 'orange', '2': 'apple', length: 3 } |
Summary
- The copyWithin method allows us to copy elements within an array to another location within the same array
- It will overwrite the elements at target location
- copyWithin does not change the length of the array. But it will mutate the array
- The syntax is
Array.copyWithin(target, start, end)
- If any of the arguments is -ve. Then it will start the count from the end of the array. You can add
array.length
to get the correct argument. - The copyWithin method preserves empty slots.
- copyWithin does a shallow copy
- copyWithin is a generic method. It will also work on array-like objects