[6a3a178] | 1 | var assignMergeValue = require('./_assignMergeValue'),
|
---|
| 2 | cloneBuffer = require('./_cloneBuffer'),
|
---|
| 3 | cloneTypedArray = require('./_cloneTypedArray'),
|
---|
| 4 | copyArray = require('./_copyArray'),
|
---|
| 5 | initCloneObject = require('./_initCloneObject'),
|
---|
| 6 | isArguments = require('./isArguments'),
|
---|
| 7 | isArray = require('./isArray'),
|
---|
| 8 | isArrayLikeObject = require('./isArrayLikeObject'),
|
---|
| 9 | isBuffer = require('./isBuffer'),
|
---|
| 10 | isFunction = require('./isFunction'),
|
---|
| 11 | isObject = require('./isObject'),
|
---|
| 12 | isPlainObject = require('./isPlainObject'),
|
---|
| 13 | isTypedArray = require('./isTypedArray'),
|
---|
| 14 | safeGet = require('./_safeGet'),
|
---|
| 15 | toPlainObject = require('./toPlainObject');
|
---|
| 16 |
|
---|
| 17 | /**
|
---|
| 18 | * A specialized version of `baseMerge` for arrays and objects which performs
|
---|
| 19 | * deep merges and tracks traversed objects enabling objects with circular
|
---|
| 20 | * references to be merged.
|
---|
| 21 | *
|
---|
| 22 | * @private
|
---|
| 23 | * @param {Object} object The destination object.
|
---|
| 24 | * @param {Object} source The source object.
|
---|
| 25 | * @param {string} key The key of the value to merge.
|
---|
| 26 | * @param {number} srcIndex The index of `source`.
|
---|
| 27 | * @param {Function} mergeFunc The function to merge values.
|
---|
| 28 | * @param {Function} [customizer] The function to customize assigned values.
|
---|
| 29 | * @param {Object} [stack] Tracks traversed source values and their merged
|
---|
| 30 | * counterparts.
|
---|
| 31 | */
|
---|
| 32 | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
|
---|
| 33 | var objValue = safeGet(object, key),
|
---|
| 34 | srcValue = safeGet(source, key),
|
---|
| 35 | stacked = stack.get(srcValue);
|
---|
| 36 |
|
---|
| 37 | if (stacked) {
|
---|
| 38 | assignMergeValue(object, key, stacked);
|
---|
| 39 | return;
|
---|
| 40 | }
|
---|
| 41 | var newValue = customizer
|
---|
| 42 | ? customizer(objValue, srcValue, (key + ''), object, source, stack)
|
---|
| 43 | : undefined;
|
---|
| 44 |
|
---|
| 45 | var isCommon = newValue === undefined;
|
---|
| 46 |
|
---|
| 47 | if (isCommon) {
|
---|
| 48 | var isArr = isArray(srcValue),
|
---|
| 49 | isBuff = !isArr && isBuffer(srcValue),
|
---|
| 50 | isTyped = !isArr && !isBuff && isTypedArray(srcValue);
|
---|
| 51 |
|
---|
| 52 | newValue = srcValue;
|
---|
| 53 | if (isArr || isBuff || isTyped) {
|
---|
| 54 | if (isArray(objValue)) {
|
---|
| 55 | newValue = objValue;
|
---|
| 56 | }
|
---|
| 57 | else if (isArrayLikeObject(objValue)) {
|
---|
| 58 | newValue = copyArray(objValue);
|
---|
| 59 | }
|
---|
| 60 | else if (isBuff) {
|
---|
| 61 | isCommon = false;
|
---|
| 62 | newValue = cloneBuffer(srcValue, true);
|
---|
| 63 | }
|
---|
| 64 | else if (isTyped) {
|
---|
| 65 | isCommon = false;
|
---|
| 66 | newValue = cloneTypedArray(srcValue, true);
|
---|
| 67 | }
|
---|
| 68 | else {
|
---|
| 69 | newValue = [];
|
---|
| 70 | }
|
---|
| 71 | }
|
---|
| 72 | else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
---|
| 73 | newValue = objValue;
|
---|
| 74 | if (isArguments(objValue)) {
|
---|
| 75 | newValue = toPlainObject(objValue);
|
---|
| 76 | }
|
---|
| 77 | else if (!isObject(objValue) || isFunction(objValue)) {
|
---|
| 78 | newValue = initCloneObject(srcValue);
|
---|
| 79 | }
|
---|
| 80 | }
|
---|
| 81 | else {
|
---|
| 82 | isCommon = false;
|
---|
| 83 | }
|
---|
| 84 | }
|
---|
| 85 | if (isCommon) {
|
---|
| 86 | // Recursively merge objects and arrays (susceptible to call stack limits).
|
---|
| 87 | stack.set(srcValue, newValue);
|
---|
| 88 | mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
|
---|
| 89 | stack['delete'](srcValue);
|
---|
| 90 | }
|
---|
| 91 | assignMergeValue(object, key, newValue);
|
---|
| 92 | }
|
---|
| 93 |
|
---|
| 94 | module.exports = baseMergeDeep;
|
---|