Cloning an Object in Node.js

Cloning an Object in Node.js

What is the best way to clone an object in node.js
e.g. I want to avoid the situation where:
var obj1 = {x: 5, y:5};
var obj2 = obj1;
obj2.x = 6;
console.log(obj1.x); // logs 6

The object may well contain complex types as attributes, so a simple for(var x in obj1) wouldn’t solve. Do I need to write a recursive clone myself or is there something built in that I’m not seeing?

Solutions/Answers:

Solution 1:

Possibility 1

Low-frills deep copy:

var obj2 = JSON.parse(JSON.stringify(obj1));

Possibility 2 (deprecated)

Attention: This solution is now marked as deprecated in the documentation of Node.js:

The util._extend() method was never intended to be used outside of internal Node.js modules. The community found and used it anyway.

It is deprecated and should not be used in new code. JavaScript comes with very similar built-in functionality through Object.assign().

Original answer::

For a shallow copy, use Node’s built-in util._extend() function.

var extend = require('util')._extend;

var obj1 = {x: 5, y:5};
var obj2 = extend({}, obj1);
obj2.x = 6;
console.log(obj1.x); // still logs 5

Source code of Node’s _extend function is in here: https://github.com/joyent/node/blob/master/lib/util.js

exports._extend = function(origin, add) {
  // Don't do anything if add isn't an object
  if (!add || typeof add !== 'object') return origin;

  var keys = Object.keys(add);
  var i = keys.length;
  while (i--) {
    origin[keys[i]] = add[keys[i]];
  }
  return origin;
};

Solution 2:

I’m surprised Object.assign hasn’t been mentioned.

let cloned = Object.assign({}, source);

If available (e.g. Babel), you can use the object spread operator:

let cloned = { ... source };

Solution 3:

Object.defineProperty(Object.prototype, "extend", {
    enumerable: false,
    value: function(from) {
        var props = Object.getOwnPropertyNames(from);
        var dest = this;
        props.forEach(function(name) {
            if (name in dest) {
                var destination = Object.getOwnPropertyDescriptor(from, name);
                Object.defineProperty(dest, name, destination);
            }
        });
        return this;
    }
});

This will define an extend method that you can use. Code comes from this article.

Related:  Chrome thinks 99,999 is drastically different than 100,000

Solution 4:

var obj2 = JSON.parse(JSON.stringify(obj1));

Solution 5:

You can use the extend function from JQuery:

var newClone= jQuery.extend({}, oldObject);  
var deepClone = jQuery.extend(true, {}, oldObject); 

There is a Node.js Plugin too:

https://github.com/shimondoodkin/nodejs-clone-extend

To do it without JQuery or Plugin read this here:

http://my.opera.com/GreyWyvern/blog/show.dml/1725165

Solution 6:

Check out underscore.js. It has both clone and extend and many other very useful functions.

This can be useful: Using the Underscore module with Node.js