This means, when you try to copy it with const newArray = oldArray, it will copy the reference to the original array and not copy the values.
const beers = ['🍺', '🍺', '🍺'];
const beersCopy = beers;
console.log(beers === beersCopy);
// The console output will be true, because it's pointing to the exact value in memory.
Shallow Copy Arrays
When copying or cloning arrays the data type of the value is key to decide what method can be used.
If your array only contains primitive immutables values (numbers, booleans, strings, etc.), you can use the following methods.
- .push
- … (spread)
- .slice -Array.from
- _.clone (lodash) .push() A classic array method and the most obvious approach, basically looping over the original array and using the push() method to push elements from the original in the new array.
We simply loop over the original array and push each element to the new array.
const arr = [1, 2, 3];
const newArr = [];
for (let i = 0; i < arr.length; i++) {
newArr.push(arr[i]);
}
… (spread)
The spread operator is one of the fastest methods and was introduced with ES6. It’s clean and simple and a native method (sorry lodash).
const arr = [1, 2, 3];
const newArr = [...arr];
.slice()
The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end arr.slice([start[, end]]). The original array will not be modified. This is the fastest way to copy an array.
const arr = [1, 2, 3];
const newArr = arr.slice();
Array.from
The Array.from() static method creates a new, shallow-copied Array instance from an array-like or iterable object (Map or Set).
It also takes a optional mapping function as the second parameter Array.from(arrayLike [, mapFn [, thisArg]]).
const arr = [1, 2, 3];
const newArr = Array.from(arr);
_.clone()
The _.clone(value) method from lodash creates a shallow clone of value. It performs well and if you use lodash already in your application it is a viable option.
// import lodash
const _ = require('lodash');
const arr = [1, 2, 3];
const newArr = _.clone(arr);
Deep Copy Arrays
All methods above create shallow copies of arrays. If you have objects as array items, and you try to make a shallow copy, the actual array will be copied, BUT the underlying objects will be passed by reference to the new array.
Let’s have a look at this issue with a code example.
const arr = [
{
name: 'mario',
food: 'pizza',
},
{
name: 'luigi',
food: 'spaghetti',
},
];
const arrCopy = [...arr];
console.log(arr === arrCopy);
// This will return false, because the array has been copied (shallow copy), new reference in memory.
console.log(arr[0] === arrCopy[0]);
// This will return true, because the reference points to the same place in memory.
There are several methods to create a deep clone.
jQuery.extend()
_.clonedeep()
JSON (stringify/parse)
jQuery.extend()
If you still use jQuery in your project, you can use the extend method from jQuery.
const arr = [
{
name: 'mario',
food: 'pizza',
},
{
name: 'luigi',
food: 'spaghetti',
},
];
const arrCopy = jQuery.extend(true, [], arr);
console.log(arr === arrCopy);
// This will return false, because the array has been copied (new reference in memory).
console.log(arr[0] === arrCopy[0]);
// This will return false, because the reference points to a new one in memory.
_.cloneDeep()
The method _.cloneDeep(value) from Lodash does exactly the same thing as _.clone(), except that it recursively clones everything in the array.
const arr = [
{
name: 'mario',
food: 'pizza',
},
{
name: 'luigi',
food: 'spaghetti',
},
];
// import lodash
const _ = require('lodash');
const arrCopy = _.cloneDeep(arr);
console.log(arr === arrCopy);
// This will return false, because the array has been copied (new reference in memory).
console.log(arr[0] === arrCopy[0]);
// This will return false, because the reference points to a new one in memory.
JSON methods
JavaScript provides native methods for serialization and deserialization, basically to convert most data types to a JSON string, and then a valid JSON string to an object.
It can be used like this:
const arr = [
{
name: 'mario',
food: 'pizza',
},
{
name: 'luigi',
food: 'spaghetti',
},
];
const arrCopy = JSON.parse(JSON.stringify(arr));
console.log(arr === arrCopy);
// This will return false, because the array has been copied (new reference in memory).
console.log(arr[0] === arrCopy[0]);
// This will return false, because the reference points to a new one in memory.
There are some advantages and disadvantages, when using this approach. An advantage is that it doesn’t require a third-party library like Lodash. The disadvantage is that the provided array data needs be serializable and the serializing and deserializing via JSON takes some time, hence this is not the fastest approach.
Top comments (3)
hi!
what about
new_ar = ar.map(i => ({ ...i }))
?
It looks like you’re using JavaScript and working with arrays. The code you provided:
javascript
Copy code
new_ar = ar.map(i => ({ ...i }));
creates a new array new_ar by mapping over each element i in the original array ar. For each element, it creates a shallow copy of the object using the spread operator { ...i }.
Here’s a breakdown of what’s happening:
ar.map(...) is iterating over each element in the array ar.
For each element i, { ...i } creates a new object that is a shallow copy of i.
So ... It works and it is in the scope of your page. Isn't it?