tdp-js-object-merge

A small commonjs module which recursively merges (true merge, non-replacing) two or more Javascript objects. It is based on the underscore.js merge function.


Keywords
javascript, nodejs, npm, merge, recursive, object
License
CC-BY-SA-3.0
Install
npm install tdp-js-object-merge@0.1.1-alpha

Documentation

TDPJSObjectMerge

Version

Master: v0.1.1-alpha
Travis CI build status icon Coverage Status Dependency Status

Overview

A small commonjs module which recursively merges (true merge, non-replacing) two or more Javascript objects (where 'objects' are true objects and also arrays). It is based on the underscorejs merge function.

TDPJSObjectMerge should work fine in NodeJS or in the browser although my tests are currently nodeJS only. Travis is hooked in and testing NodeJS 0.10, 0.11 (older builds of node aren't compatible with some of the test modules but should actually work with this module) - the current/latest Travis build status is shown above.

Installation

Installation is as simple as either a git clone or an npm install. Ensure you have git or npm installed as appropriate and then either:

git clone method:

git clone https://github.com/neilstuartcraig/TDPJSObjectMerge.git

or...

npm method:

npm install tdp-js-object-merge

Constructor

The constructor is very simple and since the module is function-scoped, it requires the 'new' syntax in the constructor to instantiate a new instance e.g.:

var TDPJSObjectMerge=require("tdp-js-object-merge");
var tjom=new TDPJSObjectMerge();

Usage

Since the module is very small, usage is correspondingly simple. There is one public function:

merge(objA, objB[,...objN])

merge() takes two or more (multi-dimensional) kavascript objects and recursively merges them together. The merge is what I would call a true merge in that it does not overwrite sub-objects in their entirety (at any dimension of the objects to be merged), rather it overwrites any matching properties and adds any which are mising.

Processing is done with an order of precedence which runs from left (low precedence) to right (high precedence). Therefore properties on the left-most object (e.g. objA as per above) in the arguments list are overwritten by any matching properties of objects further right (e.g. objN as per above) in the arguments list.

Arguments

As per above, merge() takes two or more arguments, both of which must be valid javascript objects.

Returns

merge() returns a single javascript object which is the resulting merged object.

Errors

merge() will never (intentionally) throw an error.

Full example

A simple, full example (adapted from the tests included):

var TDPJSObjectMerge=require("tdp-json-object-merge");
var tjom=new TDPJSObjectMerge();

var objA=
{
    propBool:true,
    propInt:1,
    propStr:"This is a string v1",
    propObj:
    {
        ca:"cb", c1:123
    },
    propArr:[1,2,3,4,5,6,7,8,9],
    propFunc:function pfa(){return true;}
};

var objB=
{
    propBool:false,
    propInt:-1,
    propStr:"This is a string v2",
    propObj:
    {
        ca:"bc", c1:321
    },
    propArr:[9,8,7,6,5,4,3,2,1],
    propFunc:function pfb(){return false;}
};

var tstObj={propObj:{newProp:{n:"new", dis:{guy:"alien"}}}};

var res=tjm.merge(objA, objB, tstObj);

/*
{ 
    propBool: false,
    propInt: -1,
    propStr: 'This is a string v2',
    propObj: { ca: 'bc', c1: 321, newProp: { n: 'new', dis: {guy: "alien"} } },
    propArr: [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ],
    propFunc: [Function: pfb]
}
*/

Tests

Tests currently use Mocha and should.js and are run via Travis CI.

Known issues

Currently, the original object(S) get(s) clobbered so if that matters, you may want to copy your object(s) and run it on the copy (the presumably delete the copy).

I will aim to fix this at some point but if you care enough and have a solution then pull requests will be happily reviewed/accepted!

License

TDPJSObjectMerge is issued under a Creative Commons attribution share-alike license. This means you can share and adapt the code provided you attribute the original author(s) and you share your resulting source code. If, for some specific reason you need to use this library under a different license then please contact me and i'll see what I can do - though I should mention that I am committed to all my code being open-source so closed licenses will almost certainly not be possible.