The Lodash method defaultsDeep exported as a module for recursive assignment of default properties
npx @tessl/cli install tessl/npm-lodash--defaultsdeep@4.6.0The Lodash method defaultsDeep exported as a standalone module for recursive assignment of default properties. This method is like _.defaults except that it recursively assigns default properties from source objects to a destination object, providing deep merging capabilities with preservation of existing values.
npm install lodash.defaultsdeepconst defaultsDeep = require('lodash.defaultsdeep');For ES modules:
import defaultsDeep from "lodash.defaultsdeep";const defaultsDeep = require('lodash.defaultsdeep');
// Basic deep merging
const result = defaultsDeep(
{ user: { name: 'barney' } },
{ user: { name: 'fred', age: 36 } }
);
// => { user: { name: 'barney', age: 36 } }
// Multiple sources
const config = defaultsDeep(
{ database: { host: 'localhost' } },
{ database: { host: 'remote', port: 5432, ssl: true } },
{ database: { timeout: 30000 } }
);
// => { database: { host: 'localhost', port: 5432, ssl: true, timeout: 30000 } }Recursively assigns default properties from source objects to a destination object. Only assigns properties that are undefined in the destination, preserving existing values including null.
/**
* Recursively assigns default properties from source objects to destination object.
* This method mutates the destination object and returns it.
*
* @param {Object} object - The destination object (mutated and returned)
* @param {...Object} sources - The source objects (variable number of arguments)
* @returns {Object} Returns the mutated destination object
*/
function defaultsDeep(object, ...sources);Behavior:
undefined in the destinationnull values)undefined values with source valuesUsage Examples:
// Preserves existing values
const target = { a: { b: null } };
const source = { a: { b: 2, c: 3 } };
defaultsDeep(target, source);
// => { a: { b: null, c: 3 } }
// Overwrites undefined values
const target2 = { a: { b: undefined } };
const source2 = { a: { b: 2 } };
defaultsDeep(target2, source2);
// => { a: { b: 2 } }
// Handles functions correctly
const target3 = {};
const source3 = { a: { b: function() { return 'hello'; } } };
defaultsDeep(target3, source3);
// => { a: { b: [Function] } }
// Multiple sources (left-to-right precedence)
const result = defaultsDeep(
{ a: { b: 2 } },
{ a: { b: 3, c: 3 } },
{ a: { c: 4, d: 4 } }
);
// => { a: { b: 2, c: 3, d: 4 } }
// Prevents string-to-array merging
const target4 = { a: ['abc'] };
const source4 = { a: 'abc' };
defaultsDeep(target4, source4);
// => { a: ['abc'] }const object = { a: { b: null } };
const source = { a: { b: 2 } };
defaultsDeep(object, source);
// => { a: { b: null } } - null values are preservedconst object = { a: { b: undefined } };
const source = { a: { b: 2 } };
defaultsDeep(object, source);
// => { a: { b: 2 } } - undefined values are overwrittenconst fn = function() { return 'test'; };
const object = {};
const source = { a: fn };
defaultsDeep(object, source);
// => { a: [Function] } - functions are preserved as-isconst object = { foo: { b: { c: {} } } };
const source = { foo: { b: { c: {} } } };
object.foo.b.c.d = object;
source.foo.b.c.d = source;
const result = defaultsDeep(object, source);
// Handles circular references without infinite recursionconst source1 = { a: 1, b: { c: 2 } };
const source2 = { b: { c: 3, d: 3 } };
const result = defaultsDeep({}, source1, source2);
// Source objects remain unchanged
console.log(source1); // => { a: 1, b: { c: 2 } }
console.log(source2); // => { b: { c: 3, d: 3 } }