Ensure _.defaultsDeep works on circular references.

This commit is contained in:
John-David Dalton
2015-08-10 23:08:34 -07:00
parent d6dc7627b9
commit edc03287aa

View File

@@ -2278,13 +2278,13 @@
key = srcValue; key = srcValue;
srcValue = source[key]; srcValue = source[key];
} }
if (isObjectLike(srcValue)) { if (isObject(srcValue)) {
stackA || (stackA = []); stackA || (stackA = []);
stackB || (stackB = []); stackB || (stackB = []);
baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
} }
else { else {
var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source) : undefined; var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stackA, stackB) : undefined;
if (newValue === undefined) { if (newValue === undefined) {
newValue = srcValue; newValue = srcValue;
} }
@@ -2318,7 +2318,7 @@
return; return;
} }
} }
var newValue = customizer ? customizer(oldValue, srcValue, (key + ''), object, source) : undefined, var newValue = customizer ? customizer(oldValue, srcValue, (key + ''), object, source, stackA, stackB) : undefined,
isCommon = newValue === undefined; isCommon = newValue === undefined;
if (isCommon) { if (isCommon) {
@@ -2334,7 +2334,7 @@
: (isPlainObject(oldValue) ? oldValue : {}); : (isPlainObject(oldValue) ? oldValue : {});
} }
else { else {
isCommon = false; isCommon = isFunction(srcValue);
} }
} }
// Add the source value to the stack of traversed objects and associate // Add the source value to the stack of traversed objects and associate
@@ -4072,13 +4072,16 @@
* @param {*} sourceValue The source object property value. * @param {*} sourceValue The source object property value.
* @returns {*} Returns the value to assign to the destination object. * @returns {*} Returns the value to assign to the destination object.
*/ */
function mergeDefaults(objectValue, sourceValue) { function mergeDefaults(objectValue, sourceValue, key, object, source, stackA, stackB) {
if (objectValue === undefined) { if (objectValue === undefined) {
return sourceValue; return sourceValue;
} }
return isObject(objectValue) if (isObject(objectValue)) {
? mergeWith(objectValue, sourceValue, mergeDefaults) stackA.push(objectValue);
: objectValue; stackB.push(objectValue);
return baseMerge(objectValue, sourceValue, mergeDefaults, stackA, stackB);
}
return objectValue;
} }
/** /**
@@ -9193,8 +9196,8 @@
* This method is like `_.merge` except that it accepts `customizer` which * This method is like `_.merge` except that it accepts `customizer` which
* is invoked to produce the merged values of the destination and source * is invoked to produce the merged values of the destination and source
* properties. If `customizer` returns `undefined` merging is handled by the * properties. If `customizer` returns `undefined` merging is handled by the
* method instead. The `customizer` is invoked with five arguments: * method instead. The `customizer` is invoked with seven arguments:
* (objectValue, sourceValue, key, object, source). * (objectValue, sourceValue, key, object, source, stackA, stackB).
* *
* @static * @static
* @memberOf _ * @memberOf _