Treehouse

Clone Arrays with JavaScript

By on  

Believe it or not, there are reasons we use JavaScript frameworks outside of animations and those sexy accordions that people can't do without. The further you get into high-powered JavaScript applications (assuming you're creating true web applications, not websites), the more the need for basic JavaScript functionalities; i.e. JavaScript utilities that have nothing to do with DOM. One of those basic utilities is the ability to clone an array. Quite often I see developers iterating over array items to create their clone; in reality, cloning an array can be as easy as a slice!

The JavaScript

To clone the contents of a given array, all you need to do is call slice, providing 0 as the first argument:

var clone = myArray.slice(0);

The code above creates clone of the original array; keep in mind that if objects exist in your array, the references are kept; i.e. the code above does not do a "deep" clone of the array contents. To add clone as a native method to arrays, you'd do something like this:

Array.prototype.clone = function() {
	return this.slice(0);
};

And there you have it! Don't iterate over arrays to clone them if all you need is a naive clone!

ydkjs-4.png

Recent Features

  • Create a CSS Cube

    CSS cubes really showcase what CSS has become over the years, evolving from simple color and dimension directives to a language capable of creating deep, creative visuals.  Add animation and you've got something really neat.  Unfortunately each CSS cube tutorial I've read is a bit...

  • Facebook Open Graph META Tags

    It's no secret that Facebook has become a major traffic driver for all types of websites.  Nowadays even large corporations steer consumers toward their Facebook pages instead of the corporate websites directly.  And of course there are Facebook "Like" and "Recommend" widgets on every website.  One...

Incredible Demos

  • Send Email Notifications for Broken Images Using jQuery AJAX

    It's usually best to repair broken image paths as soon as possible because they can damage a website's credibility. And even worse is having a user tell you about it. Using jQuery and PHP, you can have your page automatically notify you of broken...

  • CSS Rounded Corners

    The ability to create rounded corners with CSS opens the possibility of subtle design improvements without the need to include images.  CSS rounded corners thus save us time in creating images and requests to the server.  Today, rounded corners with CSS are supported by all of...

Discussion

  1. faruzzy

    This is a great tip! so worth it!

  2. Interesting tip!

  3. Just to note, I use .slice() all the time without passing in ‘zero’ and have never seen an issue. So even though the MDN docs do not say it is optional, it appears to work just fine with no arguments :)

  4. Mark

    It is also much faster, especially for large arrays. Here’s a benchmark I put together:

    http://jsperf.com/loop-vs-slice-copy/3

  5. What is the differences between clonearr=originalarr and clonearr=originalarr.slice(0) ?

  6. jonathan de montalembert

    I don’t understand, why not use clone = myArray?

  7. Stefan

    Mesuutt and Jonathan: doing cloneArr = originalArr will only copy the pointer of the array and not clone it:
    var a = [1,2,3]; // a.length == 3
    b = a; // a.length == 3 and b.length == 3
    b.push(4); // a.length == 4 and b.length == 4

    Another great feature of the slice function is that you can use it to convert array like objects (such as node lists and the arguments object) to real arrays using Array.prototype.slice.call :)

    • thanks @stefan, I understand exactly now :)

  8. There’s a subtle bug that can result from adding something to the prototype of Array. If you iterate over arrays with using for...in construct:

    var a = [3,7,9];
    for (var i in a) {
      console.log(i);
    }
    

    Note that the for loop will also iterate over the case when i == “clone”!
    To be safe, you must iterate by using the length property:

    for (var i=0; i<a.length; i++) {
      console.log(i);
    }
    
  9. Eric H.

    Take note: if your array is filled with objects, those objects remain linked:

    var aAll = [{x:0, y:0}, {x:1, y:1}],
    aAll1 =aAll.slice(0);
    console.log(aAll[0].x, aAll1[0].x); // 0, 0
    aAll1[0].x += 10
    console.log(aAll[0].x, aAll1[0].x); // 10, 10
    aAll1[0] = {};
    console.log(aAll[0].x, aAll1[0].x); // 10, undefined

  10. MikeOne

    So what if I need to create a clone of an array filled with objects? I cannot have the objects to be by reference in the clone. Iteration my only option?

  11. Scott S. McCoy

    No one noticed this empties the array in question? That’s not exactly a clone.

    • Scott S. McCoy

      It’s really lame you cannot delete or edit comments here.

      Use slice() not splice().

  12. Maybe it’s worth mentioning in a comment, this is very similar to how Python copies lists (arrays)

    my_list = [1, 2, "some text"];
    
    // To create a refrence
    my_ref = my_list
    
    // To create a copy
    my_copy = my_list[:]
    
  13. Adding Array.prototype.clone as mentioned in this article is a terrible idea… as it’s only a shallow clone, and if another developer on your team will use your clone method, they can trip up over this.

  14. Hi, thx for solution, exactly what Iwas looking for

  15. Hi.
    I know this post is kinda old, but we were on a discussion about it around here, and we prepared these tests.
    http://jsperf.com/array-content-copy/2
    many interesting thing around here!
    for instance, array.slice is the fastest on google chrome, while in firefox, array.concat was the fastest.
    Another interesting thing is the way the browser optimizes the most verbose test, which is not the slowest one!

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Use Code Editor