* A specialized version of `baseMerge` for arrays and objects which performs * deep merges and tracks traversed objects enabling objects with circular * references to be merged. * * @private * @param {Object} object The destination object. * @par
(object, source, key, srcIndex, mergeFunc, customizer, stack)
| 14262 | * counterparts. |
| 14263 | */ |
| 14264 | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { |
| 14265 | var objValue = safeGet(object, key), |
| 14266 | srcValue = safeGet(source, key), |
| 14267 | stacked = stack.get(srcValue); |
| 14268 | |
| 14269 | if (stacked) { |
| 14270 | assignMergeValue(object, key, stacked); |
| 14271 | return; |
| 14272 | } |
| 14273 | var newValue = customizer |
| 14274 | ? customizer(objValue, srcValue, (key + ''), object, source, stack) |
| 14275 | : undefined; |
| 14276 | |
| 14277 | var isCommon = newValue === undefined; |
| 14278 | |
| 14279 | if (isCommon) { |
| 14280 | var isArr = isArray(srcValue), |
| 14281 | isBuff = !isArr && isBuffer(srcValue), |
| 14282 | isTyped = !isArr && !isBuff && isTypedArray(srcValue); |
| 14283 | |
| 14284 | newValue = srcValue; |
| 14285 | if (isArr || isBuff || isTyped) { |
| 14286 | if (isArray(objValue)) { |
| 14287 | newValue = objValue; |
| 14288 | } |
| 14289 | else if (isArrayLikeObject(objValue)) { |
| 14290 | newValue = copyArray(objValue); |
| 14291 | } |
| 14292 | else if (isBuff) { |
| 14293 | isCommon = false; |
| 14294 | newValue = cloneBuffer(srcValue, true); |
| 14295 | } |
| 14296 | else if (isTyped) { |
| 14297 | isCommon = false; |
| 14298 | newValue = cloneTypedArray(srcValue, true); |
| 14299 | } |
| 14300 | else { |
| 14301 | newValue = []; |
| 14302 | } |
| 14303 | } |
| 14304 | else if (isPlainObject(srcValue) || isArguments(srcValue)) { |
| 14305 | newValue = objValue; |
| 14306 | if (isArguments(objValue)) { |
| 14307 | newValue = toPlainObject(objValue); |
| 14308 | } |
| 14309 | else if (!isObject(objValue) || isFunction(objValue)) { |
| 14310 | newValue = initCloneObject(srcValue); |
| 14311 | } |
| 14312 | } |
| 14313 | else { |
| 14314 | isCommon = false; |
| 14315 | } |
| 14316 | } |
| 14317 | if (isCommon) { |
| 14318 | // Recursively merge objects and arrays (susceptible to call stack limits). |
| 14319 | stack.set(srcValue, newValue); |
| 14320 | mergeFunc(newValue, srcValue, srcIndex, customizer, stack); |
| 14321 | stack['delete'](srcValue); |
no test coverage detected