object clone jquery vs underscore vs lodash (v3)

Revision 3 of this benchmark created on


Preparation HTML

<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script>
var lodash = _.noConflict();
</script>

Setup

function clone(obj) {
      var target = {};
      for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
          target[i] = obj[i];
        }
      }
      return target;
    }
    
    function deepclone(src) {
        function mixin(dest, source, copyFunc) {
                var name, s, i, empty = {};
                for(name in source){
                        // the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
                        // inherited from Object.prototype.      For example, if dest has a custom toString() method,
                        // don't overwrite it with the toString() method that source inherited from Object.prototype
                        s = source[name];
                        if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
                                dest[name] = copyFunc ? copyFunc(s) : s;
                        }
                }
                return dest;
        }
    
        if(!src || typeof src != "object" || Object.prototype.toString.call(src) === "[object Function]"){
                // null, undefined, any non-object, or function
                return src;     // anything
        }
        if(src.nodeType && "cloneNode" in src){
                // DOM Node
                return src.cloneNode(true); // Node
        }
        if(src instanceof Date){
                // Date
                return new Date(src.getTime()); // Date
        }
        if(src instanceof RegExp){
                // RegExp
                return new RegExp(src);   // RegExp
        }
        var r, i, l;
        if(src instanceof Array){
                // array
                r = [];
                for(i = 0, l = src.length; i < l; ++i){
                        if(i in src){
                                r.push(clone(src[i]));
                        }
                }
                // we don't clone functions for performance reasons
                //              }else if(d.isFunction(src)){
                //                      // function
                //                      r = function(){ return src.apply(this, arguments); };
        }else{
                // generic objects
                r = src.constructor ? new src.constructor() : {};
        }
        return mixin(r, src, clone);
    
    }
    
    var deepObject = {
      a: {
        b: {
          c: 6
        },
        d: 8
      },
      e: "hello",
      p: 9,
      q: 10,
      r: true,
      s: new Date(),
      t: function () {
        var foo = 'bar';
        return foo;
      },
      v: [1, 2, 3],
      __proto__: {
        constructor: function(){},
        __proto__: {}
      }
    };

Test runner

Ready to run.

Testing in
TestOps/sec
jQuery Deep Clone
$.extend(true, {}, deepObject);
ready
Underscore
_.clone(deepObject)
ready
Lo-dash
lodash.cloneDeep(deepObject)
ready
JSON
JSON.parse(JSON.stringify(deepObject));
ready
Lo-dash extend
lodash.extend({}, deepObject)
ready
clone
clone( deepObject )
ready
deep clone
deepclone( deepObject )
ready

Revisions

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