How can I clone an array in javascript without using JSON.stringify or JSON.parse?
I have an example of an array fruit
. I would like to copy it as an array fruits2
without keeping the references.
As in the following example, the link is preserved, so it is fruits
changed.
var fruit = function (name){
this.name = name;
}
var fruits = [];
fruits.push(new fruit('apple'));
fruits.push(new fruit('banana'));
fruits.push(new fruit('orange'));
var fruits2 = fruits;
fruits2.length = 0;
console.log(fruits);
Using JSON.stringify and JSON.parse does the trick, but the objects in fruits2
no longer have a type fruit
, but have a common typeobject
var temp = JSON.stringify(fruits);
var fruits2 = JSON.parse(temp);
I would like to know an alternative approach that would preserve the internal object fruit
.
source to share
Use slice
: var fruits2 = fruits.slice();
to do this.
jsFiddle modified
See also: MDN
** Edit . I was a little lazy, let me correct my answer to compensate for this.
For Array
values only, it slice
is perfect. For Array
objects or arrays or a combination of values / objects / arrays, cloning items Array
and Object
for cloning Array
also need to be cloned. Otherwise, they will be references to the original arrays or objects (so: not copies), and a change to one [these references to arrays or objects] will be reflected in all "clones" containing a reference to it.
To clone Array
arrays / objects / mixed values Array.map
if your friend. There are several ways to think:
- creating a new instance with old data
var fruits1 = fruits.map(function(v) {return new Fruit(v.name);});
- using JSON
var fruits2 = fruits.map(function(v) {return JSON.parse(JSON.stringify(v));});
- create and use some cloning method
var fruits3 = fruits.map(function(v) {return cloneObj(v);});
In case 3, the cloning method might look like this:
function cloneObj(obj) {
function clone(o, curr) {
for (var l in o){
if (o[l] instanceof Object) {
curr[l] = cloneObj(o[l]);
} else {
curr[l] = o[l];
}
}
return curr;
}
return obj instanceof Array
? obj.slice().map( function (v) { return cloneObj(v); } )
: obj instanceof Object
? clone(obj, {})
: obj;
}
Using this method cloneObj
is Array.map
deprecated.
You can also usevar fruitsx = cloneObj(fruits);
The jsFiddle from the link above has been modified to demonstrate these methods.
For Array.map
, see again MDN
source to share