Deep cloning an Object/Array

JavaScript performance comparison

Revision 40 of this test case created

Info

There is no quick and easy facility for cloning an object, Some people recommend using JQuery.extend others JSON.parse/stringify

http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object

If you want the fastest possible clone function. I would personally anticipate the data structure of your object and write a custom clone to handle it.

Preparation code

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
 
<script>
Benchmark.prototype.setup = function() {
    var oldObject = {
      a: 1,
      b: {
        c: [33],
        r: 9
      },
      d: 4,
      e: 5,
      f: function() {
        return 6;
      },
      g: [7, 8, [9, 10]],
      h: {
        i: {
          j: {
            k: {
              l: [11, 22]
            }
          }
        }
      }
    };
   
    var oldArray = [1, {
        c: [33],
        r: 9
      },
      4, 5,
      function() {
        return 6;
      },
      [7, 8, [9, 10]], {
        i: {
          j: {
            k: {
              l: [11, 22]
            }
          }
        }
      }
    ];
   
    function clone_recursive(obj) {
      var n = {};
      if (obj instanceof Array) {
        n = [];
      }
   
      function deepCopy(obj, obj1) {
        var i
        for (i in obj) {
          if (obj[i] instanceof Object) {
            if (obj[i] instanceof Array) {
              obj1[i] = [];
            } else {
              obj1[i] = {};
            }
            deepCopy(obj[i], obj1[i]);
          } else {
            obj1[i] = obj[i];
          }
        }
   
        return n;
      }
      deepCopy(obj, n);
      return n;
    }
   
   
    function clone_iterative(object) {
      var result = {};
      if (object instanceof Array) {
        result = [];
      }
      var stack = [result, object];
      var curr, base;
      while (curr = stack.pop()) {
        var base = stack.pop();
        for (var key in curr) {
          var value = curr[key];
          if (typeof value === 'object') {
            if (value instanceof Array) {
              stack.push(base[key] = []);
            } else {
              stack.push(base[key] = {});
            }
   
            stack.push(value)
          } else {
            base[key] = value;
          }
        }
      }
      return result;
    }
};
</script>

Preparation code output

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
jQuery.extend() deep
var newObject = jQuery.extend(true, {}, oldObject);
var newArray = jQuery.extend(true, [], oldArray);
pending…
JSON stringify/parse
var newObject = JSON.parse(JSON.stringify(oldObject));
var newArray = JSON.parse(JSON.stringify(oldArray));
pending…
clone Recursive
var newObject = clone_recursive(oldObject);
var newArray = clone_recursive(oldArray);
pending…
Clone Iterative
var newObject = clone_iterative(oldObject);
var newArray = clone_iterative(oldArray);
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

0 comments

Add a comment