Merge
Merge and extend objects.
Installation
$ npm install utils-merge2
Usage
var merge = require( 'utils-merge2' );
merge( target, source1[, source2[,...,sourceN]] )
Merges and extends a target object
.
var target = {
'a': 'beep'
};
var source = {
'a': 'boop',
'b': 'bap'
};
var out = merge( target, source );
The function
supports merging multiple source objects
.
var target = {
'a': 'beep'
};
var source1 = {
'b': 'boop'
};
var source2 = {
'c': 'cat'
};
var out = merge( target, source1, source2 );
merge.factory( options )
Returns a custom merge function
for merging and extending objects
.
var factory = require( 'utils-merge2' ).factory;
var opts = {
'level': 100,
'copy': true,
'override': true,
'extend': true
};
var merge = factory( opts );
The function
accepts the following options
:
- level: limits the merge depth. The default merge strategy is a deep (recursive) merge. Default:
level = +infinity
. - copy:
boolean
indicating whether to deep copy merged values. Deep copying prevents shared references and source object
mutation. Default: true
. - override: defines the merge strategy. If
true
, source object
values will always override target object
values. If false
, source values never override target values (useful for adding, but not overwriting, properties). To define a custom merge strategy, provide a function
. Default: true
. - extend:
boolean
indicating whether new properties can be added to the target object
. If false
, only shared properties are merged. Default: true
.
The default merge is a deep (recursive) merge.
var target = {
'a': {
'b': {
'c': 5
},
'd': 'beep'
}
};
var source = {
'a': {
'b': {
'c': 10
}
}
};
var out = merge( target, source );
To limit the merge depth, set the level
option.
var merge = factory({
'level': 2
});
var target = {
'1': {
'a': 'beep',
'2': {
'3': null,
'b': [ 5, 6, 7 ]
}
}
};
var source = {
'1': {
'b': 'boop',
'2': {
'3': [ 1, 2, 3 ]
}
}
};
var out = merge( target, source );
By default, merged values are deep copied.
var target = {
'a': null
};
var source = {
'a': {
'b': [ 1, 2, 3 ]
}
};
var out = merge( target, source );
console.log( out.a.b === source.a.b );
To allow shared references, set the copy
option to false
.
var merge = factory({
'copy': false
});
var target = {};
var source = {
'a': [ 1, 2, 3 ]
};
var out = merge( target, source );
var bool = ( out.a === source.a );
To prevent existing properties from being overridden, set the override
option to false
.
var merge = factory({
'override': false
});
var target = {
'a': 'beep',
'b': 'boop'
};
var source = {
'a': null,
'c': 'bop'
};
var out = merge( target, source );
Alternatively, to define a custom merge strategy, set the override
option to a function
.
function strategy( a, b, key ) {
if ( key === 'a' ) {
return b;
}
if ( key === 'b' ) {
return a;
}
return 'bebop';
}
var merge = factory({
'override': strategy
});
var target = {
'a': 'beep',
'b': 'boop',
'c': 1234
};
var source = {
'a': null,
'b': {},
'c': 'bop'
};
var out = merge( target, source );
To prevent non-existent properties from being added to the target object
, set the extend
option to false
.
var merge = factory({
'extend': false
});
var target = {
'a': 'beep',
'b': 'boop'
};
var source = {
'b': 'hello',
'c': 'world'
};
var out = merge( target, source );
Notes
-
The target object
is mutated.
var target = {
'a': 'beep'
};
var source = {
'b': 'boop'
};
var out = merge( target, source );
console.log( out === target );
console.log( target.b );
To return a new object
, provide an empty object
as the first argument.
var target = {
'a': 'beep'
};
var source = {
'b': 'boop'
};
var out = merge( {}, target, source );
console.log( out === target );
-
Only plain JavaScript objects
are merged and extended. The following values/types are either deep copied or assigned:
Boolean
String
Number
Date
RegExp
Array
Int8Array
Uint8Array
Uint8ClampedArray
Init16Array
Uint16Array
Int32Array
Uint32Array
Float32Array
Float64Array
Buffer
(Node.js)Set
Map
Error
URIError
ReferenceError
SyntaxError
RangeError
-
Support for deep merging class instances is inherently fragile.
-
Number
, String
, or Boolean
objects are merged as primitives.
-
Functions are not deep copied.
Examples
var merge = require( 'utils-merge2' );
var target;
var source;
var out;
target = {
'a': 'beep',
'b': 'boop',
'c': {
'c1': 'woot',
'c2': false,
'c3': {
'c3a': [ 1, 2 ],
'c3b': null
}
},
'd': [ 1, 2, 3 ]
};
source = {
'b': Math.PI,
'c': {
'c1': 'bap',
'c3': {
'c3b': 5,
'c3c': 'bop'
},
'c4': 1337,
'c5': new Date()
},
'd': [ 4, 5, 6 ],
'e': true
};
out = merge( {}, target, source );
console.dir( out );
To run the example code from the top-level application directory,
$ node ./examples/index.js
Tests
Unit
This repository uses tape for unit tests. To run the tests, execute the following command in the top-level application directory:
$ make test
All new feature development should have corresponding unit tests to validate correct functionality.
Test Coverage
This repository uses Istanbul as its code coverage tool. To generate a test coverage report, execute the following command in the top-level application directory:
$ make test-cov
Istanbul creates a ./reports/coverage
directory. To access an HTML version of the report,
$ make view-cov
Browser Support
This repository uses Testling for browser testing. To run the tests in a (headless) local web browser, execute the following command in the top-level application directory:
$ make test-browsers
To view the tests in a local web browser,
$ make view-browser-tests
License
MIT license.
Copyright
Copyright © 2015-2016. Athan Reines.