[javascript] 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?

This question is related to javascript node.js

The answer is


This code is also work cause The Object.create() method creates a new object with the specified prototype object and properties.

var obj1 = {x:5, y:5};

var obj2 = Object.create(obj1);

obj2.x; //5
obj2.x = 6;
obj2.x; //6

obj1.x; //5

Y'all suffering yet the solution is simple.

var obj1 = {x: 5, y:5};

var obj2 = {...obj1}; // Boom


You can prototype object and then call object instance every time you want to use and change object:

function object () {
  this.x = 5;
  this.y = 5;
}
var obj1 = new object();
var obj2 = new object();
obj2.x = 6;
console.log(obj1.x); //logs 5

You can also pass arguments to object constructor

function object (x, y) {
   this.x = x;
   this.y = y;
}
var obj1 = new object(5, 5);
var obj2 = new object(6, 6);
console.log(obj1.x); //logs 5
console.log(obj2.x); //logs 6

Hope this is helpful.


There is also a project on Github that aims to be a more direct port of the jQuery.extend():

https://github.com/dreamerslab/node.extend

An example, modified from the jQuery docs:

var extend = require('node.extend');

var object1 = {
    apple: 0,
    banana: {
        weight: 52,
        price: 100
    },
    cherry: 97
};

var object2 = {
    banana: {
        price: 200
    },
    durian: 100
};

var merged = extend(object1, object2);

Simple and the fastest way to clone an Object in NodeJS is to use Object.keys( obj ) method

var a = {"a": "a11", "b": "avc"};
var b;

for(var keys = Object.keys(a), l = keys.length; l; --l)
{
   b[ keys[l-1] ] = a[ keys[l-1] ];
}
b.a = 0;

console.log("a: " + JSON.stringify(a)); // LOG: a: {"a":"a11","b":"avc"} 
console.log("b: " + JSON.stringify(b)); // LOG: b: {"a":0,"b":"avc"}

The method Object.keys requires JavaScript 1.8.5; nodeJS v0.4.11 supports this method

but of course for nested objects need to implement recursive func


Other solution is to use native JSON (Implemented in JavaScript 1.7), but it's much slower (~10 times slower) than previous one

var a = {"a": i, "b": i*i};
var b = JSON.parse(JSON.stringify(a));
b.a = 0;

You can also use this clone library to deep clone objects.

 npm install --save clone
const clone = require('clone');

const clonedObject = clone(sourceObject);


None of the answers satisfied me, several don't work or are just shallow clones, answers from @clint-harris and using JSON.parse/stringify are good but quite slow. I found a module that does deep cloning fast: https://github.com/AlexeyKupershtokh/node-v8-clone


There are some Node modules out there if don't want to "roll your own". This one looks good: https://www.npmjs.com/package/clone

Looks like it handles all kinds of stuff, including circular references. From the github page:

clone masters cloning objects, arrays, Date objects, and RegEx objects. Everything is cloned recursively, so that you can clone dates in arrays in objects, for example. [...] Circular references? Yep!


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

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

You can also use SugarJS in NodeJS.

http://sugarjs.com/

They have a very clean clone feature: http://sugarjs.com/api/Object/clone


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.


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


Another solution is to encapsulate directly in the new variable using: obj1= {...obj2}


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


There is another library lodash, it has clone and cloneDeep.

clone will clone your object but not create a new instance for non-primitive values, instead it will use the referrence to the original object

cloneDeep will create literally new objects without having any referrence to the original object, so it more safe when you have to change the object afterwards.


If you're using coffee-script, it's as easy as:

newObject = {}
newObject[key] = value  for own key,value of oldObject

Though this isn't a deep clone.


There is no built-in way to do a real clone (deep copy) of an object in node.js. There are some tricky edge cases so you should definitely use a library for this. I wrote such a function for my simpleoo library. You can use the deepCopy function without using anything else from the library (which is quite small) if you don't need it. This function supports cloning multiple data types, including arrays, dates, and regular expressions, it supports recursive references, and it also works with objects whose constructor functions have required parameters.

Here is the code:

//If Object.create isn't already defined, we just do the simple shim, without the second argument,
//since that's all we need here
var object_create = Object.create;
if (typeof object_create !== 'function') {
    object_create = function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

/**
 * Deep copy an object (make copies of all its object properties, sub-properties, etc.)
 * An improved version of http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
 * that doesn't break if the constructor has required parameters
 * 
 * It also borrows some code from http://stackoverflow.com/a/11621004/560114
 */ 
function deepCopy = function deepCopy(src, /* INTERNAL */ _visited) {
    if(src == null || typeof(src) !== 'object'){
        return src;
    }

    // Initialize the visited objects array if needed
    // This is used to detect cyclic references
    if (_visited == undefined){
        _visited = [];
    }
    // Ensure src has not already been visited
    else {
        var i, len = _visited.length;
        for (i = 0; i < len; i++) {
            // If src was already visited, don't try to copy it, just return the reference
            if (src === _visited[i]) {
                return src;
            }
        }
    }

    // Add this object to the visited array
    _visited.push(src);

    //Honor native/custom clone methods
    if(typeof src.clone == 'function'){
        return src.clone(true);
    }

    //Special cases:
    //Array
    if (Object.prototype.toString.call(src) == '[object Array]') {
        //[].slice(0) would soft clone
        ret = src.slice();
        var i = ret.length;
        while (i--){
            ret[i] = deepCopy(ret[i], _visited);
        }
        return ret;
    }
    //Date
    if (src instanceof Date) {
        return new Date(src.getTime());
    }
    //RegExp
    if (src instanceof RegExp) {
        return new RegExp(src);
    }
    //DOM Element
    if (src.nodeType && typeof src.cloneNode == 'function') {
        return src.cloneNode(true);
    }

    //If we've reached here, we have a regular object, array, or function

    //make sure the returned object has the same prototype as the original
    var proto = (Object.getPrototypeOf ? Object.getPrototypeOf(src): src.__proto__);
    if (!proto) {
        proto = src.constructor.prototype; //this line would probably only be reached by very old browsers 
    }
    var ret = object_create(proto);

    for(var key in src){
        //Note: this does NOT preserve ES5 property attributes like 'writable', 'enumerable', etc.
        //For an example of how this could be modified to do so, see the singleMixin() function
        ret[key] = deepCopy(src[key], _visited);
    }
    return ret;
};

Looking for a true clone option, I stumbled across ridcully's link to here:

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

I modified the solution on that page so that the function attached to the Object prototype is not enumerable. Here is my result:

Object.defineProperty(Object.prototype, 'clone', {
    enumerable: false,
    value: function() {
        var newObj = (this instanceof Array) ? [] : {};
        for (i in this) {
        if (i == 'clone') continue;
            if (this[i] && typeof this[i] == "object") {
                newObj[i] = this[i].clone();
            } else newObj[i] = this[i]
        } return newObj;
    }
});

Hopefully this helps someone else as well. Note that there are some caveats... particularly with properties named "clone". This works well for me. I don't take any credit for writing it. Again, I only changed how it was being defined.


npm install node-v8-clone

Fastest cloner, it open native clone method from node.js

var clone = require('node-v8-clone').clone;
var newObj = clone(obj, true); //true - deep recursive clone