95 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			95 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | var assignMergeValue = require('./_assignMergeValue'), | ||
|  |     cloneBuffer = require('./_cloneBuffer'), | ||
|  |     cloneTypedArray = require('./_cloneTypedArray'), | ||
|  |     copyArray = require('./_copyArray'), | ||
|  |     initCloneObject = require('./_initCloneObject'), | ||
|  |     isArguments = require('./isArguments'), | ||
|  |     isArray = require('./isArray'), | ||
|  |     isArrayLikeObject = require('./isArrayLikeObject'), | ||
|  |     isBuffer = require('./isBuffer'), | ||
|  |     isFunction = require('./isFunction'), | ||
|  |     isObject = require('./isObject'), | ||
|  |     isPlainObject = require('./isPlainObject'), | ||
|  |     isTypedArray = require('./isTypedArray'), | ||
|  |     safeGet = require('./_safeGet'), | ||
|  |     toPlainObject = require('./toPlainObject'); | ||
|  | 
 | ||
|  | /** | ||
|  |  * 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. | ||
|  |  * @param {Object} source The source object. | ||
|  |  * @param {string} key The key of the value to merge. | ||
|  |  * @param {number} srcIndex The index of `source`. | ||
|  |  * @param {Function} mergeFunc The function to merge values. | ||
|  |  * @param {Function} [customizer] The function to customize assigned values. | ||
|  |  * @param {Object} [stack] Tracks traversed source values and their merged | ||
|  |  *  counterparts. | ||
|  |  */ | ||
|  | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { | ||
|  |   var objValue = safeGet(object, key), | ||
|  |       srcValue = safeGet(source, key), | ||
|  |       stacked = stack.get(srcValue); | ||
|  | 
 | ||
|  |   if (stacked) { | ||
|  |     assignMergeValue(object, key, stacked); | ||
|  |     return; | ||
|  |   } | ||
|  |   var newValue = customizer | ||
|  |     ? customizer(objValue, srcValue, (key + ''), object, source, stack) | ||
|  |     : undefined; | ||
|  | 
 | ||
|  |   var isCommon = newValue === undefined; | ||
|  | 
 | ||
|  |   if (isCommon) { | ||
|  |     var isArr = isArray(srcValue), | ||
|  |         isBuff = !isArr && isBuffer(srcValue), | ||
|  |         isTyped = !isArr && !isBuff && isTypedArray(srcValue); | ||
|  | 
 | ||
|  |     newValue = srcValue; | ||
|  |     if (isArr || isBuff || isTyped) { | ||
|  |       if (isArray(objValue)) { | ||
|  |         newValue = objValue; | ||
|  |       } | ||
|  |       else if (isArrayLikeObject(objValue)) { | ||
|  |         newValue = copyArray(objValue); | ||
|  |       } | ||
|  |       else if (isBuff) { | ||
|  |         isCommon = false; | ||
|  |         newValue = cloneBuffer(srcValue, true); | ||
|  |       } | ||
|  |       else if (isTyped) { | ||
|  |         isCommon = false; | ||
|  |         newValue = cloneTypedArray(srcValue, true); | ||
|  |       } | ||
|  |       else { | ||
|  |         newValue = []; | ||
|  |       } | ||
|  |     } | ||
|  |     else if (isPlainObject(srcValue) || isArguments(srcValue)) { | ||
|  |       newValue = objValue; | ||
|  |       if (isArguments(objValue)) { | ||
|  |         newValue = toPlainObject(objValue); | ||
|  |       } | ||
|  |       else if (!isObject(objValue) || isFunction(objValue)) { | ||
|  |         newValue = initCloneObject(srcValue); | ||
|  |       } | ||
|  |     } | ||
|  |     else { | ||
|  |       isCommon = false; | ||
|  |     } | ||
|  |   } | ||
|  |   if (isCommon) { | ||
|  |     // Recursively merge objects and arrays (susceptible to call stack limits).
 | ||
|  |     stack.set(srcValue, newValue); | ||
|  |     mergeFunc(newValue, srcValue, srcIndex, customizer, stack); | ||
|  |     stack['delete'](srcValue); | ||
|  |   } | ||
|  |   assignMergeValue(object, key, newValue); | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = baseMergeDeep; |