Deep cloning an Object/Array (v42)

Revision 42 of this benchmark created by robertsky on


Description

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 HTML

<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>

Setup

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;
    }

Test runner

Ready to run.

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

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.