Combine or merge JSON on node.js without jQuery

Solution 1:

You should use "Object.assign()"

There's no need to reinvent the wheel for such a simple use case of shallow merging.

The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.

var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed

Even the folks from Node.js say so:

_extend was never intended to be used outside of internal NodeJS 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.


Update:

You could use the spread operator

Since version 8.6, it's possible to natively use the spread operator in Node.js. Example below:

let o1 = { a: 1 };
let o2 = { b: 2 };
let obj = { ...o1, ...o2 }; // { a: 1, b: 2 }

Object.assign still works, though.


PS1: If you are actually interested in deep merging (in which internal object data -- in any depth -- is recursively merged), you can use packages like deepmerge, assign-deep or lodash.merge, which are pretty small and simple to use.

PS2: Keep in mind that Object.assign doesn't work with 0.X versions of Node.js. If you are working with one of those versions (you really shouldn't by now), you could use require("util")._extend as shown in the Node.js link above -- for more details, check tobymackenzie's answer to this same question.

Solution 2:

If using Node version >= 4, use Object.assign() (see Ricardo Nolde's answer).

If using Node 0.x, there is the built in util._extend:

var extend = require('util')._extend
var o = extend({}, {name: "John"});
extend(o,  {location: "San Jose"});

It doesn't do a deep copy and only allows two arguments at a time, but is built in. I saw this mentioned on a question about cloning objects in node: https://stackoverflow.com/a/15040626.

If you're concerned about using a "private" method, you could always proxy it:

// myutil.js
exports.extend = require('util')._extend;

and replace it with your own implementation if it ever disappears. This is (approximately) their implementation:

exports.extend = function(origin, add) {
    if (!add || (typeof add !== 'object' && add !== null)){
        return origin;
    }

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

Solution 3:

Underscore's extend is the easiest and quickest way to achieve this, like James commented.

Here's an example using underscore:

var _ = require('underscore'), // npm install underscore to install
  object1 = {name: "John"},
  object2 = {location: "San Jose"};

var target = _.extend(object1, object2);

object 1 will get the properties of object2 and be returned and assigned to target. You could do it like this as well, depending on whether you mind object1 being modified:

var target = {};
_.extend(target, object1, object2);

Solution 4:

A normal loop?

function extend(target) {
    var sources = [].slice.call(arguments, 1);
    sources.forEach(function (source) {
        for (var prop in source) {
            target[prop] = source[prop];
        }
    });
    return target;
}

var object3 = extend({}, object1, object2);

That's a basic starting point. You may want to add things like a hasOwnProperty check, or add some logic to handle the case where multiple source objects have a property with the same identifier.

Here's a working example.

Side note: what you are referring to as "JSON" are actually normal JavaScript objects. JSON is simply a text format that shares some syntax with JavaScript.

Solution 5:

Use merge.

$ npm install merge

Sample code:

var merge = require('merge'), // npm install -g merge
    original, cloned;

console.log(

    merge({ one: 'hello' }, { two: 'world' })

); // {"one": "hello", "two": "world"}

original = { x: { y: 1 } };

cloned = merge(true, original);

cloned.x.y++;

console.log(original.x.y, cloned.x.y); // 1, 2