mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-05 17:37:50 +00:00
Ensure _.merge ignores undefined values of source object properties. [closes #573]
This commit is contained in:
23
lodash.js
23
lodash.js
@@ -1962,7 +1962,8 @@
|
|||||||
* @returns {Object} Returns the destination object.
|
* @returns {Object} Returns the destination object.
|
||||||
*/
|
*/
|
||||||
function baseMerge(object, source, callback, stackA, stackB) {
|
function baseMerge(object, source, callback, stackA, stackB) {
|
||||||
(isArrayLike(source) ? arrayEach : baseForOwn)(source, function(srcValue, key, source) {
|
var isSrcArr = isArrayLike(source);
|
||||||
|
(isSrcArr ? arrayEach : baseForOwn)(source, function(srcValue, key, source) {
|
||||||
var isArr = srcValue && isArrayLike(srcValue),
|
var isArr = srcValue && isArrayLike(srcValue),
|
||||||
isObj = srcValue && isPlainObject(srcValue),
|
isObj = srcValue && isPlainObject(srcValue),
|
||||||
value = object[key];
|
value = object[key];
|
||||||
@@ -1972,10 +1973,9 @@
|
|||||||
if (typeof result == 'undefined') {
|
if (typeof result == 'undefined') {
|
||||||
result = srcValue;
|
result = srcValue;
|
||||||
}
|
}
|
||||||
if (typeof result != 'undefined') {
|
if (isSrcArr || typeof result != 'undefined') {
|
||||||
value = result;
|
object[key] = result;
|
||||||
}
|
}
|
||||||
object[key] = value;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// avoid merging previously merged cyclic sources
|
// avoid merging previously merged cyclic sources
|
||||||
@@ -1992,22 +1992,21 @@
|
|||||||
var result = callback ? callback(value, srcValue, key, object, source) : undefined,
|
var result = callback ? callback(value, srcValue, key, object, source) : undefined,
|
||||||
isShallow = typeof result != 'undefined';
|
isShallow = typeof result != 'undefined';
|
||||||
|
|
||||||
if (isShallow) {
|
if (!isShallow) {
|
||||||
value = result;
|
result = isArr
|
||||||
} else {
|
|
||||||
value = isArr
|
|
||||||
? (isArray(value) ? value : [])
|
? (isArray(value) ? value : [])
|
||||||
: (isPlainObject(value) ? value : {});
|
: (isPlainObject(value) ? value : {});
|
||||||
}
|
}
|
||||||
// add `source` and associated `value` to the stack of traversed objects
|
// add the source value to the stack of traversed objects
|
||||||
|
// and associate it with its merged value
|
||||||
stackA.push(srcValue);
|
stackA.push(srcValue);
|
||||||
stackB.push(value);
|
stackB.push(result);
|
||||||
|
|
||||||
// recursively merge objects and arrays (susceptible to call stack limits)
|
// recursively merge objects and arrays (susceptible to call stack limits)
|
||||||
if (!isShallow) {
|
if (!isShallow) {
|
||||||
baseMerge(value, srcValue, callback, stackA, stackB);
|
baseMerge(result, srcValue, callback, stackA, stackB);
|
||||||
}
|
}
|
||||||
object[key] = value;
|
object[key] = result;
|
||||||
});
|
});
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
|
|||||||
34
test/test.js
34
test/test.js
@@ -2580,22 +2580,6 @@
|
|||||||
|
|
||||||
deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
|
deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
|
||||||
});
|
});
|
||||||
|
|
||||||
if (methodName == 'merge') {
|
|
||||||
test('`_.' + methodName + '` should treat sparse arrays as dense', 2, function() {
|
|
||||||
var array = Array(3);
|
|
||||||
array[0] = 1;
|
|
||||||
array[2] = 3;
|
|
||||||
|
|
||||||
var actual = func([], array),
|
|
||||||
expected = array.slice();
|
|
||||||
|
|
||||||
expected[1] = undefined;
|
|
||||||
|
|
||||||
ok('1' in actual);
|
|
||||||
deepEqual(actual, expected);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
@@ -6365,6 +6349,20 @@
|
|||||||
ok(actual.bar.b === actual.foo.b && actual.foo.b.foo.c === actual.foo.b.foo.c.foo.b.foo.c);
|
ok(actual.bar.b === actual.foo.b && actual.foo.b.foo.c === actual.foo.b.foo.c.foo.b.foo.c);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should treat sources that are sparse arrays as dense', 2, function() {
|
||||||
|
var array = Array(3);
|
||||||
|
array[0] = 1;
|
||||||
|
array[2] = 3;
|
||||||
|
|
||||||
|
var actual = _.merge([], array),
|
||||||
|
expected = array.slice();
|
||||||
|
|
||||||
|
expected[1] = undefined;
|
||||||
|
|
||||||
|
ok('1' in actual);
|
||||||
|
deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
|
||||||
test('should not treat `arguments` objects as plain objects', 1, function() {
|
test('should not treat `arguments` objects as plain objects', 1, function() {
|
||||||
var object = {
|
var object = {
|
||||||
'args': args
|
'args': args
|
||||||
@@ -6389,8 +6387,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should not assign `undefined` values', 1, function() {
|
test('should not assign `undefined` values', 1, function() {
|
||||||
var actual = _.merge({ 'a': 1 }, { 'a': undefined });
|
var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
|
||||||
strictEqual(actual.a, 1);
|
deepEqual(actual, { 'a': 1 });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should handle merging if `callback` returns `undefined`', 1, function() {
|
test('should handle merging if `callback` returns `undefined`', 1, function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user