Skip to main content

Shallow copy of an array

A shallow copy of an array is a new array with its own reference, holding the top-level elements of the original. Primitives are copied by value, while nested objects and arrays are copied by reference, so they stay shared with the original.

Theory

TL;DR

  • A shallow copy creates a new array, so copy === arr is false and top-level changes do not touch the original.
  • The shortest way is the spread syntax: const copy = [...arr].
  • arr.slice(), Array.from(arr) and [].concat(arr) do exactly the same thing.
  • All of them copy the top level only: nested objects and arrays remain shared.
  • Replacing a whole element of the copy is safe; mutating a field inside a nested object is not.
  • For a deep copy you need structuredClone(arr) or JSON.parse(JSON.stringify(arr)).

Quick example

javascript
const arr = [1, 2, 3]; const copy = [...arr]; console.log(copy); // [1, 2, 3] console.log(copy === arr); // false (this is a new array)

The spread operator

The spread syntax ... expands the elements of an array into a new array literal. It is the most modern and the shortest form, and it is the one an interviewer expects to hear.

javascript
const arr = [1, 2, 3]; const copy = [...arr]; console.log(copy); // [1, 2, 3] console.log(copy === arr); // false (a new array)

The copy is still shallow: if the elements were objects, they keep pointing at the same data.

javascript
const arr = [{ name: 'Tim' }]; const copy = [...arr]; copy[0].name = 'Alex'; console.log(arr[0].name); // "Alex", because the object is shared

slice(), Array.from() and concat()

slice() with no arguments returns a new array, a copy of the whole source. The approach is old but perfectly reliable:

javascript
const arr = [1, 2, 3]; const copy = arr.slice(); console.log(copy); // [1, 2, 3]

Array.from() builds a new array out of an iterable or array-like value:

javascript
const arr = [1, 2, 3]; const copy = Array.from(arr); console.log(copy); // [1, 2, 3]

It is handy when you want more than a plain copy, for instance a copy with every element transformed:

javascript
const doubled = Array.from(arr, x => x * 2); // [2, 4, 6]

concat() works because it returns a new array instead of mutating the source:

javascript
const arr = [1, 2, 3]; const copy = [].concat(arr); console.log(copy); // [1, 2, 3]

What stays shared

Every method above copies the top level only. If the array holds objects or nested arrays, those are kept by reference.

javascript
const arr = [[1, 2], [3, 4]]; const copy = [...arr]; copy[0][0] = 99; console.log(arr[0][0]); // 99, because the nested array is shared

Replacing a whole element of the copy, on the other hand, leaves the original alone, because you change a slot of the new array rather than the shared object:

javascript
copy[0] = [7, 8]; console.log(arr[0]); // [99, 2], the original is unchanged

Comparison of the options

OptionCodeCreates a new arrayDeep copy
Spread[...arr]YesNo
slice()arr.slice()YesNo
Array.from()Array.from(arr)YesNo
concat()[].concat(arr)YesNo

The takeaway is simple: to make a shallow copy of an array, write const copy = [...arr];.

Deep copying

When the nested structures have to be copied too, a shallow copy is not enough:

javascript
const deep = structuredClone(arr);

structuredClone() is built into modern browsers and Node.js, handles Map, Set, Date, typed arrays and circular references, but cannot copy functions. The older trick JSON.parse(JSON.stringify(arr)) is simpler, yet it drops undefined and functions, turns a Date into a string and throws on circular references.

Common mistakes

  • Assuming [...arr] gives a fully independent array: nested objects remain shared.
  • Confusing copying with assignment: const copy = arr creates no array at all, it is the same reference.
  • Reaching for JSON.parse(JSON.stringify(arr)) on an array with Date values or functions and then wondering where the data went.
  • Believing slice() mutates the array: it returns a new one, unlike splice(), which changes the source.
  • Copying an array with a manual push() loop where a single spread expression is enough.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.