diff --git a/index.js b/index.js index 1f614f1..962a6d9 100644 --- a/index.js +++ b/index.js @@ -56,16 +56,20 @@ function propertyIsUnsafe(target, key) { } // Retrieves either a new object or the appropriate target object to mutate. -function getDestinationObject(target, options) { - if (options && options.mergeWithTarget) { +function getDestinationObject(target, source, options) { + const targetDefined = typeof target !== 'undefined' + const isArray = Array.isArray(target) || Array.isArray(source) + const doMerge = options && (options.mergeWithTarget || options.clone === false) + + if (targetDefined && doMerge) { return Array.isArray(target) ? firstArrayEntry(target) : target } - return {} + return isArray ? [] : {}; } function mergeObject(target, source, options) { - var destination = getDestinationObject(target, options) + var destination = getDestinationObject(target, source, options) if (options.isMergeableObject(target)) { getKeys(target).forEach(function(key) { destination[key] = cloneUnlessOtherwiseSpecified(target[key], options) @@ -113,7 +117,7 @@ deepmerge.all = function deepmergeAll(array, options) { return array.reduce(function(prev, next) { return deepmerge(prev, next, options) - }, getDestinationObject(array, options)) + }, getDestinationObject(array, undefined, options)) } module.exports = deepmerge diff --git a/test/merge.js b/test/merge.js index c37b1fc..9cd3801 100644 --- a/test/merge.js +++ b/test/merge.js @@ -1,6 +1,18 @@ var merge = require('../') var test = require('tape') +test('should handle an undefined value in the target object when merging', function(t) { + var src = { key1: 'value1', key2: { key4: 'value4'}, key3: ['value3'] } + var target = { key1: 'value', key2: undefined, key3: undefined } + + var notClonedRes = merge(target, src, {mergeWithTarget: true}) + + t.assert(notClonedRes === target, 'should successfully merge mutating target'); + t.assert(notClonedRes.key2 instanceof Object, 'should successfully merge object'); + t.assert(Array.isArray(notClonedRes.key3), 'should successfully merge array'); + t.end() +}) + test('result should retain target type information when mergeWithTarget set to true', function(t) { var src = { key1: 'value1', key2: 'value2' } class CustomType {}