cloning an object (v48)

Revision 48 of this benchmark created 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="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.7.0/lodash.min.js"></script>

Setup

var oldObject = {
                "name": "street_addr",
                "fieldType": "addresses.address1",
                "actions": [
                    {
                        "type": "enterText",
                        "value": "720N. 10th Street",
                        "form_input_count_scaling":1,
                        "targets": [
                            {
                                "filter": [
                                    "input[type=text]"
                                ],
                                "method": {
                                    "compare": "exactCI",
                                    "objects": [
                                        "labelText",
                                        "attributeV",
                                        "tdSiblings"
                                    ]
                                },
                                "blacklist": [
                                    "zip",
                                    "postal_code",
                                    "postal code",
                                    "city",
                                    "state",
                                    "phone",
                                    "email"
                                ],
                                "values": [
                                    "Address line 1",
                                    "street address",
                                    "address",
                                    "billing address",
                                    "street address",
                                    "streetaddress",
                                    "street",
                                    "address-line1",
                                    "addr1",
                                    "addressline1"
                                ],
                                "confidence": 0.95
                            },
                            {
                                "boost_strings" : [
                                    "LineOne",
                                    "One",
                                    "1",
                                    "Line One",
                                    "Line1"
                                ],
                                "boost_objects" : [
                                    "attributeV",
                                    "labelText"
                                ],
                                "filter": [
                                    "input[type=text]"
                                ],
                                "blacklist": [
                                    "zip",
                                    "postal_code",
                                    "postal code",
                                    "city",
                                    "state",
                                    "phone",
                                    "email"
                                ],
                                "method": {
                                    "compare": "substr",
                                    "objects": [
                                        "labelText",
                                        "attributeV",
                                        "tdSiblings"
                                    ]
                                },
                                "values": [
                                    "Address line 1",
                                    "street address",
                                    "address",
                                    "billing address",
                                    "street address",
                                    "streetaddress",
                                    "street",
                                    "address-line1",
                                    "addr1",
                                    "addressline1"
                                ],
                                "confidence": 0.8
                            }
                        ],
                        "fallback" : {
                            "actions" : [
                                {
                                    "type": "click",
                                    "targets": [
                                        {
                                            "filter": [
                                                "a",
                                                "button",
                                                "select",
                                                "option"
                                            ],
                                            "method": {
                                                "compare": "exactCI",
                                                "objects": [
                                                    "eleText",
                                                    "labelText"
                                                ]
                                            },
                                            "values": [
                                                "next",
                                                "add a new address",
                                                "select a billing address"
                                            ],
                                            "confidence":0.95
                                        }
                                    ]
                                }
                            ]
                        }
                    }
                ]
            };
      
      Object.defineProperties(Object, {
       'extend': {
        'configurable': true,
        'enumerable': false,
        'value': function extend(what, wit) {
         var extObj, witKeys = Object.keys(wit);
      
         extObj = Object.keys(what).length ? Object.clone(what) : {};
      
         witKeys.forEach(function(key) {
          Object.defineProperty(extObj, key, Object.getOwnPropertyDescriptor(wit, key));
         });
      
         return extObj;
        },
        'writable': true
       },
       'clone': {
        'configurable': true,
        'enumerable': false,
        'value': function clone(obj) {
         return Object.extend({}, obj);
        },
        'writable': true
       }
      });
    
    var cloneAsync = (function() {
      var queue = [];
     
      var worker = new Worker(URL.createObjectURL(new Blob(['onmessage=function(e){postMessage(e.data)}'], {
        'type': 'text/javascript'
      })));
     
      worker.addEventListener('message', function listener(e) {
        var callback = queue.shift().callback;
        if (queue.length) {
          this.postMessage(queue[0].value);
        }
        callback(e.data);
      });
     
      return function(value, callback) {
        if (!queue.length) {
          worker.postMessage(value);
        }
        queue.push({ 'value': value, 'callback': callback });
      };
    }());

Test runner

Ready to run.

Testing in
TestOps/sec
jQuery.extend() deep
var newObject = jQuery.extend(true, {}, oldObject);
ready
JSON stringify/parse
var newObject = JSON.parse(JSON.stringify(oldObject));
ready
jQuery.extend()
var newObject = jQuery.extend({}, oldObject);
ready
lodash cloneDeep
var newObject = _.cloneDeep(oldObject)
ready
ES5 Object.clone
var newObject = Object.clone(oldObject);
ready
stringify eval
var newObject = eval("("+JSON.stringify(oldObject)+")");
ready
cloneAsync
// async test
var newObject = cloneAsync(oldObject, function(result) {
deferred.resolve();
});
ready

Revisions

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