Introduction

Array copying is often misunderstood, but not because of the copying process it-self, but due to lack of understanding of how JavaScript handles arrays and its items. Arrays in JavaScript are mutable, meaning that after an array gets created it's content can be modified.

This means that to copy an array, we cannot simply assign our old array to a new variable, which is also an array. If we do that, they will share the same reference, and after changing one, the other variable will be affected by the change as well. That is the reason why we need to clone the array.

Below are some interesting ways and tricks on how we can clone an array. Enjoy!

Do note that these methods perform a shallow copy...although, we don't have objects with deeper levels in our examples to see this in action.

Option 1 - Using the Array.slice method

const numbers = [1, 2, 3, 4, 5];

const copy = numbers.slice();
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 2 - Using the Array.map method

const numbers = [1, 2, 3, 4, 5];

const copy = numbers.map(num => num);
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 3 - Using the Array.from method

const numbers = [1, 2, 3, 4, 5];

const copy = Array.from(new Set(numbers));
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 4 - Using the spread operator

const numbers = [1, 2, 3, 4, 5];

const copy = [...numbers];
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 5 - Using the Array.of method with the spread operator

const numbers = [1, 2, 3, 4, 5];

const copy = Array.of(...numbers);
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 6 - Using the array constructor with the spread operator

const numbers = [1, 2, 3, 4, 5];

const copy = new Array(...numbers);
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 7 - Using destructuring

const numbers = [1, 2, 3, 4, 5];

const [...copy] = numbers;
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 8 - Using the Array.concat method

const numbers = [1, 2, 3, 4, 5];

const copy = numbers.concat();
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 9 - Using the Array.push method with the spread operator

const numbers = [1, 2, 3, 4, 5];

let copy = [];
copy.push(...numbers);
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 10 - Using the Array.unshift method with the spread operator

const numbers = [1, 2, 3, 4, 5];

let copy = [];
copy.unshift(...numbers);
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 11 - Using the Array.forEach method

const numbers = [1, 2, 3, 4, 5];

let copy = [];
numbers.forEach((value) => copy.push(value));
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 12 - Using the for loop

const numbers = [1, 2, 3, 4, 5];

let copy = [];
for (let i = 0; i < numbers.length; i++) {
    copy.push(numbers[i]);
}
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 13 - Using Array.reduce

This is possible, but it is an overkill, and you should prefer one of the methods above.

const numbers = [1, 2, 3, 4, 5];

const copy = numbers.reduce((acc, x) => { acc.push(x); return acc; }, []);
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Option 14 - The old, nostalgic way - using the apply method

const numbers = [1, 2, 3, 4, 5];

let copy = [];
Array.prototype.push.apply(copy, numbers);
copy.push(6); // add a new item to prove that we WILL NOT MODIFY the original array

console.log(copy);
console.log(numbers);

// output 
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]

Conclusion

I hope you find these methods useful and helpful. If so, consider buying me a coffee to keep me juiced up for more, subscribe here, or follow me on twitter to stay tuned.

Thank you for reading and see you in the next article.