By Dan


2011-09-20 13:38:08 8 Comments

When copying an array in JavaScript to another array:

var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d');  //Now, arr1 = ['a','b','c','d']

I realized that arr2 refers to the same array as arr1, rather than a new, independent array. How can I copy the array to get two independent arrays?

30 comments

@DevWL 2018-12-31 01:28:25

Primitive values are always pass by its value (copied). Compound values hovever are passed by reference.

So how do we copy this arr?

let arr = [1,2,3,4,5];

Copy an Array in ES6

let arrCopy = [...arr]; 

Copy n Array in ES5

let arrCopy = arr.slice(); 
let arrCopy = [].concat(arr);

Why `let arrCopy = arr` is not passing by value?

Passing one varible to another on Compound values such as Object/Array behave difrently. Using asign operator on copand values we pass reference to an object. This is why the value of both arrays are changing when removing/adding arr elements.

Exceptions:

arrCopy[1] = 'adding new value this way will unreference';

When you assign a new value to the variable, you are changing the reference itself and it doesn’t affect the original Object/Array.

read more

@Diemauerdk 2019-03-25 11:53:17

I would personally prefer this way:

JSON.parse(JSON.stringify( originalObject ));

@Script47 2019-03-25 11:55:36

So the way suggested here?

@Saket 2011-09-20 13:41:21

Use this:

var newArray = oldArray.slice();

Basically, the slice() operation clones the array and returns a reference to a new array.

Also note that:

For references, strings and numbers (and not the actual object), slice() copies object references into the new array. Both the original and new array refer to the same object. If a referenced object changes, the changes are visible to both the new and original arrays.

Primitives such as strings and numbers are immutable, so changes to the string or number are impossible.

@Cohen 2012-12-19 18:46:32

Regarding performance the following jsPerf tests actually show that var arr2 = arr1.slice() is just as fast as var arr2 = arr1.concat(); JSPerf: jsperf.com/copy-array-slice-vs-concat/5 and jsperf.com/copy-simple-array . The result of jsperf.com/array-copy/5 kind of surprised me to the point I am wondering if the test code is valid.

@Wayne Burkett 2014-01-20 16:29:15

Even though this has already received a ton of upvotes, it deserves another because it properly describes references in JS, which is sort of rare, unfortunately.

@dudewad 2016-02-08 19:47:23

@GáborImre you'd add an entire library simply for readability? Really? I'd just add a comment if I were that concerned for readability. See: var newArray = oldArray.slice(); //Clone oldArray to newArray

@dudewad 2016-02-09 19:48:13

@GáborImre I get that, sure. But answering a specific engineering problem by including an entire library in my opinion is not helpful, it's design bloat. I see developers do that a lot, and then you end up with a project that included an entire framework to replace having to write a single function. Just my M.O., though.

@Gábor Imre 2016-02-09 21:02:28

@dudewad Generally you are right. In this case my whole JS experience suggests using this lib in almost every project. Lodash for arrays or objects, like Moment for dates, like Express for NodeJS server, like Angular or React for frontend.

@eran otzap 2016-05-31 12:38:45

"Copying array by value in JavaScript" . The SO asked how to copy by value and you said that slice() copies the references of the objects. True that this is a new array. But i think the question was about the objects

@Dmitry 2016-08-11 21:13:48

I think specifying the index is better for "original code" and worse for "published code". Since it gives more flexibility to translate the original file to other languages such as PHP where array_slice requires the initial index, and the translation requires less "thinking" if the 0 is explicitly stated. It is worse in published code because javascript needs to do more work parsing a 0 that it already knows as default, which just makes compilation of the instruction longer(the first time, after that it is cached and javascript doesn't care).

@Growler 2017-07-11 17:48:54

So Basically, the slice() operation clones the array and returns the reference to the new array - basically this is a deep copy then

@crazypeter 2018-02-28 06:20:32

Lesson learned: Don't confuse .slice() with .splice(), which gives you an empty array. Big difference.

@kano 2018-11-27 14:37:09

@Growler definitely not a deep copy! It will keep all references to original objects.

@tfmontague 2014-05-08 08:36:15

In Javascript, deep-copy techniques depend on the elements in an array. Let's start there.

Three types of elements

Elements can be: literal values, literal structures, or prototypes.

// Literal values (type1)
const booleanLiteral = true;
const numberLiteral = 1;
const stringLiteral = 'true';

// Literal structures (type2)
const arrayLiteral = [];
const objectLiteral = {};

// Prototypes (type3)
const booleanPrototype = new Bool(true);
const numberPrototype = new Number(1);
const stringPrototype = new String('true');
const arrayPrototype = new Array();
const objectPrototype = new Object(); # or "new function () {}"

From these elements we can create three types of arrays.

// 1) Array of literal-values (boolean, number, string) 
const type1 = [true, 1, "true"];

// 2) Array of literal-structures (array, object)
const type2 = [[], {}];

// 3) Array of prototype-objects (function)
const type3 = [function () {}, function () {}];

Deep copy techniques depend on the three array types

Based on the types of elements in the array, we can use various techniques to deep copy.

Javascript deep copy techniques by element types

  • Array of literal-values (type1)
    The [...myArray], myArray.splice(0), myArray.slice(), and myArray.concat() techniques can be used to deep copy arrays with literal values (boolean, number, and string) only; where the Spread operator [...myArray] has the best performance (https://measurethat.net/Benchmarks/Show/4281/0/spread-array-performance-vs-slice-splice-concat).

  • Array of literal-values (type1) and literal-structures (type2)
    The JSON.parse(JSON.stringify(myArray)) technique can be used to deep copy literal values (boolean, number, string) and literal structures (array, object), but not prototype objects.

  • All arrays (type1, type2, type3)
    The jQuery $.extend(myArray) technique can be used to deep-copy all array-types. Libraries like Underscore and Lo-dash offer similar deep-copy functions to jQuery $.extend(), yet have lower performance. More surprisingly, $.extend() has higher performance than the JSON.parse(JSON.stringify(myArray)) technique http://jsperf.com/js-deep-copy/15.
    And for those developers that shy away from third-party libraries (like jQuery), you can use the following custom function; which has higher performance than $.extend, and deep-copies all arrays.

function copy(aObject) {
  if (!aObject) {
    return aObject;
  }

  let v;
  let bObject = Array.isArray(aObject) ? [] : {};
  for (const k in aObject) {
    v = aObject[k];
    bObject[k] = (typeof v === "object") ? copy(v) : v;
  }

  return bObject;
}

So to answer the question...

Question

var arr1 = ['a','b','c'];
var arr2 = arr1;

I realized that arr2 refers to the same array as arr1, rather than a new, independent array. How can I copy the array to get two independent arrays?

Answer

Because arr1 is an array of literal values (boolean, number, or string), you can use any deep copy technique discussed above, where the spread operator ... has the highest performance.

// Highest performance for deep copying literal values
arr2 = [...arr1];

// Any of these techniques will deep copy literal values as well,
//   but with lower performance.
arr2 = arr1.slice();
arr2 = arr1.splice(0);
arr2 = arr1.concat();
arr2 = JSON.parse(JSON.stringify(arr1));
arr2 = $.extend(true, [], arr1); // jQuery.js needed
arr2 = _.extend(arr1); // Underscore.js needed
arr2 = _.cloneDeep(arr1); // Lo-dash.js needed
arr2 = copy(arr1); // Custom-function needed - as provided above

@Dancrumb 2014-09-18 19:53:45

Many of these approaches do not work well. Using the assignment operator means that you have to reassign the original literal value of arr1. It's very rare that that's going to be the case. Using splice obliterates arr1, so that's not a copy at all. Using JSON will fail if any of the values in the array are Functions or have prototypes (such as a Date).

@tfmontague 2014-10-03 06:50:58

Using splice is a partial solution. It will fail under far more cases than JSON. Splice creates a deep-copy of strings and numbers, when it moves values - never said it returns a copy.

@helpse 2015-05-14 15:29:48

Why splice(0)? Shouldn't it be slice() ? I think it's supposed not to modify original array, which splice does. @JamesMontagne

@tfmontague 2015-05-21 09:35:47

splice will create pointers to the elements in the original array (shallow copy). splice(0) will allocate new memory (deep copy) for elements in the array which are numbers or strings, and create pointers for all other element types (shallow copy). By passing a start value of zero to the splice function-method, it won't splice any elements from the original array, and therefore it doesn't modify it.

@wizzwizz4 2016-04-07 09:12:16

Actually, there is only one type of array: an array of "somethings". There is no difference between [0,"1",{2:3},function random() {return 4;}, [[5,6,7],[8,9,10],[11,12,13]]] and any other array.

@kano 2018-11-27 14:36:03

That custom deep-copy recursive function is splendid! Thanks for sharing and for that extremely extensive answer! I had a hard time getting .slice() to work, since I was modifying an object through the reference... after the deep copy - works like a charm.

@Jonas Wilms 2019-05-22 21:25:53

Note that in most cases deep copying can be simplified if you know the structure of your array. If you have an array of objects, just do arr.map(it => ({ ...it })), if you have an array of arrays: arr.map(Array.from)

@tfmontague 2019-05-23 17:57:36

@JonasWilms - Just to be clear to the reader, and paraphrasing. "If you have an array of objects (which are not nested), just do arr.map(it => ({ ...it })), if you have an array of arrays (without elements that are objects): arr.map(Array.from)."

@Jonas Wilms 2019-05-23 18:12:34

Yes, I think its worth mentioning ... Maybe that should be part of tue answer?

@tfmontague 2019-05-24 07:31:55

@JonasWilms - That is apart of the answer. It's covered under the custom function, which uses the for-in loop (as it has higher performance than .map) to deep copy elements into a new array

@Jonas Wilms 2019-05-24 09:44:33

No it is not. A custom clone function will always be faster than one for the general case.

@tfmontague 2019-05-24 10:29:17

@JonasWilms - Regardless of performance, I don't want to add your expressions to the answer because they don't offer a new solution. They simply loop over elements in an array and make a flat copy, and that's already being done by the custom function.

@alejoko 2019-02-02 15:00:23

Just writting:

arr2 = arr1.concat();

You are generating new a new array with a copy of the first. Be aware that is a functional way to push an element into the array.

If your code is based on ES6 you can use spread operator as well:

arr2 = [...arr1];

@Nitesh Ranjan 2018-11-18 06:43:39

let a = [1,2,3];

Now you can do any one of the following to make a copy of an array.

let b = Array.from(a); 

OR

let b = [...a];

OR

let b = new Array(...a); 

OR

let b = a.slice(); 

OR

let b = a.map(e => e);

Now, if i change a,

a.push(5); 

Then, a is [1,2,3,5] but b is still [1,2,3] as it has different reference.

But i think, in all the methods above Array.from is better and made mainly to copy an array.

@Marc Frame 2019-06-07 02:11:45

which one is the fastest?

@G.Denis 2018-12-13 11:10:48

Here is how you can do it for array of arrays of primitives of variable depth:

// If a is array: 
//    then call cpArr(a) for each e;
//    else return a

const cpArr = a => Array.isArray(a) && a.map(e => cpArr(e)) || a;

let src = [[1,2,3], [4, ["five", "six", 7], true], 8, 9, false];
let dst = cpArr(src);

https://jsbin.com/xemazog/edit?js,console

@Abhinav1602 2018-09-26 13:52:41

If your array contains elements of the primitive data type such as int, char, or string etc then you can user one of those methods which returns a copy of the original array such as .slice() or .map() or spread operator(thanks to ES6).

new_array = old_array.slice()

or

new_array = old_array.map((elem) => elem)

or

const new_array = new Array(...old_array);

BUT if your array contains complex elements such as objects(or arrays) or more nested objects, then, you will have to make sure that you are making a copy of all the elements from the top level to the last level else reference of the inner objects will be used and that means changing values in object_elements in new_array will still affect the old_array. You can call this method of copying at each level as making a DEEP COPY of the old_array.

For deep copying, you can use the above-mentioned methods for primitive data types at each level depending upon the type of data or you can use this costly method(mentioned below) for making a deep copy without doing much work.

var new_array = JSON.parse(JSON.stringify(old_array));

There are a lot of other methods out there which you can use depending on your requirements. I have mentioned only some of those for giving a general idea of what happens when we try to copy an array into the other by value.

@albert sh 2019-06-19 03:07:40

Thanks a lot, your answer was the only one who worked for my scenario,

@ulou 2018-08-22 14:46:52

Important!

Most of answers here works for particular cases.

If you don't care about deep/nested objects and props use (ES6):

let clonedArray = [...array]

but if you want to do deep clone use this instead:

let cloneArray = JSON.parse(JSON.stringify(array))


For lodash users:

let clonedArray = _.clone(array) documentation

and

let clonedArray = _.cloneDeep(array) documentation

@SridharKritha 2018-09-11 13:41:24

Quick Examples:

  1. If elements in the array are primitive types (string, number, etc.)

var arr1 = ['a','b','c'];
// arr1 and arr2 are independent and primitive elements are stored in 
// different places in the memory
var arr2 = arr1.slice(); 
arr2.push('d');
console.log(arr1); // [ 'a', 'b', 'c' ]
console.log(arr2); // [ 'a', 'b', 'c', 'd' ]

  1. If elements in the array are object literals, another array ({}, [])

var arr1 = [{ x: 'a', y: 'b'}, [1, 2], [3, 4]];
// arr1 and arr2 are independent and reference's/addresses are stored in different
// places in the memory. But those reference's/addresses points to some common place
// in the memory.
var arr2 = arr1.slice(); 
arr2.pop();      // OK - don't affect arr1 bcos only the address in the arr2 is
                 // deleted not the data pointed by that address
arr2[0].x = 'z'; // not OK - affect arr1 bcos changes made in the common area 
                 // pointed by the addresses in both arr1 and arr2
arr2[1][0] = 9;	 // not OK - same above reason

console.log(arr1); // [ { x: 'z', y: 'b' }, [ 9, 2 ], [ 3, 4 ] ]
console.log(arr2); // [ { x: 'z', y: 'b' }, [ 9, 2 ] ]

  1. Solution for 2: Deep Copy by element by element

var arr1 = [{ x: 'a', y: 'b'}, [1, 2], [3, 4]];
arr2 = JSON.parse(JSON.stringify(arr1));
arr2.pop();	  // OK - don't affect arr1
arr2[0].x = 'z';  // OK - don't affect arr1
arr2[1][0] = 9;	  // OK - don't affect arr1

console.log(arr1); // [ { x: 'a', y: 'b' }, [ 1, 2 ], [ 3, 4 ] ]
console.log(arr2); // [ { x: 'z', y: 'b' }, [ 9, 2 ] ]

@Willem van der Veen 2018-08-06 10:06:27

When we want to copy an array using the assignment operator ( = ) it doesn't create a copy it merely copies the pointer/reference to the array. For example:

const oldArr = [1,2,3];

const newArr = oldArr;  // now oldArr points to the same place in memory 

console.log(oldArr === newArr);  // Points to the same place in memory thus is true

const copy = [1,2,3];

console.log(copy === newArr);  // Doesn't point to the same place in memory and thus is false

Often when we transform data we want to keep our initial datastructure (e.g. Array) intact. We do this by making a exact copy of our array so this one can be transformed while the initial one stays intact.

Ways of copying an array:

const oldArr = [1,2,3];

// Uses the spread operator to spread out old values into the new array literal
const newArr1 = [...oldArr];

// Slice with no arguments returns the newly copied Array
const newArr2 = oldArr.slice();

// Map applies the callback to every element in the array and returns a new array
const newArr3 = oldArr.map((el) => el);

// Concat is used to merge arrays and returns a new array. Concat with no args copies an array
const newArr4 = oldArr.concat();

// Object.assign can be used to transfer all the properties into a new array literal
const newArr5 = Object.assign([], oldArr);

// Creating via the Array constructor using the new keyword
const newArr6 = new Array(...oldArr);

// For loop
function clone(base) {
	const newArray = [];
    for(let i= 0; i < base.length; i++) {
	    newArray[i] = base[i];
	}
	return newArray;
}

const newArr7 = clone(oldArr);

console.log(newArr1, newArr2, newArr3, newArr4, newArr5, newArr6, newArr7);

Be careful when arrays or objects are nested!:

When arrays are nested the values are copied by reference. Here is an example of how this could lead to issues:

let arr1 = [1,2,[1,2,3]]

let arr2 = [...arr1];

arr2[2][0] = 5;  // we change arr2

console.log(arr1);  // arr1 is also changed because the array inside arr1 was copied by reference

So don't use these methods when there are objects or arrays inside your array you want to copy. i.e. Use these methods on arrays of primitives only.

If you do want to deepclone a javascript array use JSON.parse in conjunction with JSON.stringify, like this:

let arr1 = [1,2,[1,2,3]]

let arr2 = JSON.parse(JSON.stringify(arr1)) ;

arr2[2][0] = 5;

console.log(arr1);  // now I'm not modified because I'm a deep clone

Performance of copying:

So which one do we choose for optimal performance. It turns out that the most verbose method, the for loop has the highest performance. Use the for loop for really CPU intensive copying (large/many arrays).

After that the .slice() method also has decent performance and is also less verbose and easier for the programmer to implement. I suggest to use .slice() for your everyday copying of arrays which aren't very CPU intensive. Also avoid using the JSON.parse(JSON.stringify(arr)) (lots of overhead) if no deep clone is required and performance is an issue.

Source performance test

@BluePie 2018-06-27 09:06:09

You could use ES6 with spread Opeartor, its simpler.

arr2 = [...arr1];

There are limitations..check docs Spread syntax @ mozilla

@Harunur Rashid 2018-05-31 11:50:15

You can do that in following way :
arr2 = arr1.map(x => Object.assign({}, x));

@DragoRaptor 2018-05-18 15:05:09

Dan, no need to use fancy tricks. All you need to do is make copy of arr1 by doing this.

var arr2 = new Array(arr1);

Now arr1 and arr2 are two different array variables stored in separate stacks. Check this out on jsfiddle.

@Timothy003 2018-11-21 23:25:09

This doesn't copy the array. It creates an array with one element that references the original (i.e. var arr2 = [arr1];).

@askilondz 2018-05-04 19:09:16

For ES6 array containing objects

cloneArray(arr) {
    return arr.map(x => ({ ...x }));
}

@Alireza 2017-03-26 02:35:08

As we know in Javascript arrays and objects are by reference, but what ways we can do copy the array without changing the original array later one?

Here are few ways to do it:

Imagine we have this array in your code:

var arr = [1, 2, 3, 4, 5];

1) Looping through the array in a function and return a new array, like this:

 function newArr(arr) {
      var i=0, res = [];
      while(i<arr.length){
       res.push(arr[i]);
        i++;
       }
   return res;
 }

2) Using slice method, slice is for slicing part of the array, it will slice some part of your array without touching the original, in the slice, if don't specify the start and end of the array, it will slice the whole array and basically make a full copy of the array, so we can easily say:

var arr2 = arr.slice(); // make a copy of the original array

3) Also contact method, this is for merging two array, but we can just specify one of arrays and then this basically make a copy of the values in the new contacted array:

var arr2 = arr.concat();

4) Also stringify and parse method, it's not recommended, but can be an easy way to copy Array and Objects:

var arr2 = JSON.parse(JSON.stringify(arr));

5) Array.from method, this is not widely supported, before use check the support in different browsers:

const arr2 = Array.from(arr);

6) ECMA6 way, also not fully supported, but babelJs can help you if you want to transpile:

const arr2 = [...arr];

@ganesh phirke 2018-04-12 07:00:17

Here are few more way to copy:

const array = [1,2,3,4];

const arrayCopy1 = Object.values(array);
const arrayCopy2 = Object.assign([], array);
const arrayCopy3 = array.map(i => i);
const arrayCopy4 = Array.of(...array );

@Luke Femur 2015-07-03 14:46:54

You can use array spreads ... to copy arrays.

const itemsCopy = [...items];

Also if want to create a new array with the existing one being part of it:

var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];

Array spreads are now supported in all major browsers but if you need older support use typescript or babel and compile to ES5.

More info on spreads

@ankur kushwaha 2017-06-30 19:16:15

You can also use ES6 spread operator to copy Array

var arr=[2,3,4,5];
var copyArr=[...arr];

@Ashraf Sabry 2014-12-10 15:45:02

There's the newly introduced Array.from, but unfortunately, as of the time of this writing it's only supported on recent Firefox versions (32 and higher). It can be simply used as follows:

var arr1 = [1, 2, 3];
console.log(Array.from(arr1)); // Logs: [1, 2, 3]

Reference: Here

Or Array.prototype.map may be used with an identity function:

function identity(param)
{
    return param;
}

var arr1 = [1, 2, 3],
    clone = arr1.map(identity);

Reference: Here

@mgthomas99 2017-10-18 11:16:04

+1 for mentioning Array.from, which is now supported on all major browsers except Internet Explorer (source). .

@Sudhansu Choudhary 2019-07-12 20:29:37

Be aware Array.from will mutate data, doesn't provide deep copying/deep cloning.

@ink 2014-07-22 12:15:12

Make copy of multidimensional array/object:

function deepCopy(obj) {
   if (Object.prototype.toString.call(obj) === '[object Array]') {
      var out = [], i = 0, len = obj.length;
      for ( ; i < len; i++ ) {
         out[i] = arguments.callee(obj[i]);
      }
      return out;
   }
   if (typeof obj === 'object') {
      var out = {}, i;
      for ( i in obj ) {
         out[i] = arguments.callee(obj[i]);
      }
      return out;
   }
   return obj;
}

Thanks to James Padolsey for this function.

Source: Here

@Oleksandr Tsurika 2017-01-12 19:26:26

Using jQuery deep copy could be made as following:

var arr2 = $.extend(true, [], arr1);

@Lewis 2016-03-09 12:01:37

I personally think Array.from is a more readable solution. By the way, just beware of its browser support.

//clone
let x = [1,2,3];
let y = Array.from(x);

//deep clone
let clone = arr => Array.from(arr,item => Array.isArray(item) ? clone(item) : item);
let x = [1,[],[[]]];
let y = clone(x);

@Banago 2016-07-27 14:46:14

Yes, this is very readable. The .slice() solution is completely unintuitive. Thanks for this.

@Boopathi Rajaa 2015-12-24 07:14:04

From ES2015,

var arr2 = [...arr1];

@Brent Keller 2014-05-13 18:20:44

In my particular case I needed to ensure the array remained intact so this worked for me:

// Empty array
arr1.length = 0;
// Add items from source array to target array
for (var i = 0; i < arr2.length; i++) {
    arr1.push(arr2[i]);
}

@unsynchronized 2014-06-30 22:45:43

+1 for not adding obscuity to your code by calling a function that does exactly the same thing, but in a less obvious way. slice may be more efficient under the hood, but to anyone working on the code, this shows your intent. plus it makes it easier to optimise later, if you want to (for example) filter what you are copying. note however this does not handle deep copying, and the same internal objects are passed to the new array, by reference. This might be what you want to do, it might not.

@Walter Chapilliquen - wZVanG 2015-07-03 09:31:28

If you are in an environment of ECMAScript 6, using the Spread Operator you could do it this way:

var arr1 = ['a','b','c'];
var arr2 = [...arr1]; //copy arr1
arr2.push('d');

console.log(arr1)
console.log(arr2)
<script src="http://www.wzvang.com/snippet/ignore_this_file.js"></script>

@Chtiwi Malek 2014-04-23 13:32:35

This is how I've done it after trying many approaches:

var newArray = JSON.parse(JSON.stringify(orgArray));

This will create a new deep copy not related to the first one (not a shallow copy).

Also this obviously will not clone events and functions, but the good thing you can do it in one line, and it can be used for any kind of object (arrays, strings, numbers, objects ...)

@Vladimir Kharlampidi 2014-05-05 20:28:43

This is the best one. I use the same method a long time ago and think that there is no more sense in old school recursive loops

@Ruben 2014-06-28 23:12:07

Be aware that this option doesn't handle well graph-like structures: crashes in presence of cycles, and doesn't preserve shared references.

@Dancrumb 2014-09-18 19:57:08

This also fails for things like Date, or indeed, anything that has a prototype. In addition, undefineds get converted to nulls.

@Lawrence Dol 2014-12-09 23:58:55

Is no one brave enough to comment on the gross inefficiency in both CPU and memory of serializing to text and then parsing back to an object?

@user3888372 2015-09-28 11:52:44

This solution is the only one that worked. Using slice() is really a fake solution.

@AnR 2016-02-22 07:20:47

This really saved my day. Slice and Splice didn't work.

@wizzwizz4 2016-04-07 09:15:06

This does a deep copy. The question didn't ask for that. Although it is useful, it does something different than the other answers.

@Akshit Arora 2018-06-27 14:14:51

Slice or splice will not work when you have array of arrays. However, this will work well. Yes as per @LawrenceDol, it is inefficient as compared to other available methods. Use this only if you have array of arrays.

@Adas 2019-04-18 12:58:57

This is the only solution that worked, the previous answers with 500+ points did not help at all. This should be the answer

@Andris 2019-08-01 13:10:16

Best one from all for my usage case.

@sarvesh singh 2012-12-12 16:22:00

Some of mentioned methods work well when working with simple data types like number or string, but when the array contains other objects these methods fail. When we try to pass any object from one array to another it is passed as a reference, not the object.

Add the following code in your JavaScript file:

Object.prototype.clone = function() {
    var newObj = (this instanceof Array) ? [] : {};
    for (i in this) {
        if (i == 'clone') 
            continue;
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        } 
        else 
            newObj[i] = this[i]
    } return newObj;
};

And simply use

var arr1 = ['val_1','val_2','val_3'];
var arr2 = arr1.clone()

It will work.

@sawe 2013-01-21 17:56:46

i get this error when i add this code to my page 'Uncaught RangeError: Maximum call stack size exceeded'

@sarvesh singh 2013-04-10 12:12:20

On Which Browser did you see this error??

@sawe 2013-04-11 05:01:14

My apologies, this error occurs in chrome if arr1 is not declared. so i copy-pasted the above code, and i get the error, however, if i declare the array arr1, then i do not get the error. You could improve the answer by declaring arr1 just above arr2, i see there are quite a few of 'us' out there who did not recognise that we had to declare arr1 (partly because when i was evaluating your answer, i was in a rush and needed something that 'just works')

@Jason 2013-05-30 19:49:35

.slice() still works fine even if you have objects in your array: jsfiddle.net/edelman/k525g

@Samuel 2013-07-08 14:39:06

@Jason but the objects are still pointing to the same object so changing one will change the other. jsfiddle.net/k525g/1

@Jason 2013-07-08 16:32:36

@Samuel good point.

@themis 2013-08-11 18:13:25

Excellent code. One question I have, I actually tried to copy one array into another like this var arr1 = new Array() and then var arr2 = arr1; If I change something in arr2 the change happens also to arr1. However, if I use the clone prototype you made, It actually creates a complete new instance of that array or in other words it copies it. So is this a browser problem? or javascript by default sets the two variables by one pointing to an other with the use of pointers when someone does var arr2=arr1 and why does not happen with integer variables? see jsfiddle.net/themhz/HbhtA

@tomsmeding 2014-04-24 18:38:57

@themis integers and strings are basic variable types and can be natively passed by value. Anything else can't.

@Sotiris 2011-09-20 13:45:24

If you want to make a new copy of an object or array, you must explicitly copy the properties of the object or the elements of the array, for example:

var arr1 = ['a','b','c'];
var arr2 = [];

for (var i=0; i < arr1.length; i++) {
   arr2[i] = arr1[i];
}

You can search for more information on Google about immutable primitive values and mutable object references.

@Magne 2014-06-04 14:30:16

You don't have to explicitly copy the properties of the objects of the array. See Chtiwi Malek's answer.

@Ninjakannon 2012-10-18 00:11:08

An alternative to slice is concat, which can be used in 2 ways. The first of these is perhaps more readable as the intended behaviour is very clear:

var array2 = [].concat(array1);

The second method is:

var array2 = array1.concat();

Cohen (in the comments) pointed out that this latter method has better performance.

The way this works is that the concat method creates a new array consisting of the elements in the object on which it is called followed by the elements of any arrays passed to it as arguments. So when no arguments are passed, it simply copies the array.

Lee Penkman, also in the comments, points out that if there's a chance array1 is undefined, you can return an empty array as follows:

var array2 = [].concat(array1 || []);

Or, for the second method:

var array2 = (array1 || []).concat();

Note that you can also do this with slice: var array2 = (array1 || []).slice();.

@Cohen 2012-12-19 18:50:00

Actually you can also do: var array2 = array1.concat(); It's a lot faster regarding performance. (JSPerf: jsperf.com/copy-simple-array and jsperf.com/copy-array-slice-vs-concat/5

@lee penkman 2014-08-01 08:27:10

Its worth noting that if array1 isn't an array then [].concat(array1) returns [array1] e.g. if its undefined you'll get [undefined]. I sometimes do var array2 = [].concat(array1 || []);

Related Questions

Sponsored Content

15 Answered Questions

[SOLVED] Copy array items into another array

  • 2010-11-11 15:33:18
  • bba
  • 893743 View
  • 815 Score
  • 15 Answer
  • Tags:   javascript arrays

73 Answered Questions

[SOLVED] How to merge two arrays in JavaScript and de-duplicate items

39 Answered Questions

[SOLVED] Loop through an array in JavaScript

32 Answered Questions

[SOLVED] Find object by id in an array of JavaScript objects

73 Answered Questions

[SOLVED] Get all unique values in a JavaScript array (remove duplicates)

37 Answered Questions

[SOLVED] Get the first element of an array

  • 2009-12-17 12:26:44
  • hsz
  • 1264547 View
  • 975 Score
  • 37 Answer
  • Tags:   php arrays

41 Answered Questions

[SOLVED] Sort array of objects by string property value

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

54 Answered Questions

[SOLVED] Remove duplicate values from JS array

15 Answered Questions

Sponsored Content