* Extend an object, and any object it contains. * * This does not replace deep objects, but dives into them * replacing individual elements instead. * * @method extendDeep * @param mergeInto {Object} The object to merge into * @param mergeFrom... {Object} - Any number of objects
(mergeInto, ...vargs)
| 717 | * @return {Object} The altered mergeInto object is returned |
| 718 | */ |
| 719 | static extendDeep(mergeInto, ...vargs) { |
| 720 | // Initialize |
| 721 | let depth = vargs.pop(); |
| 722 | if (typeof (depth) != 'number') { |
| 723 | vargs.push(depth); |
| 724 | depth = DEFAULT_CLONE_DEPTH; |
| 725 | } |
| 726 | |
| 727 | // Recursion detection |
| 728 | if (depth < 0) { |
| 729 | return mergeInto; |
| 730 | } |
| 731 | |
| 732 | for (let mergeFrom of vargs) { |
| 733 | // Cycle through each element of the object to merge from |
| 734 | for (const prop in mergeFrom) { |
| 735 | // save original value in deferred elements |
| 736 | const fromIsDeferredFunc = mergeFrom[prop] instanceof DeferredConfig; |
| 737 | const isDeferredFunc = mergeInto[prop] instanceof DeferredConfig; |
| 738 | |
| 739 | if (fromIsDeferredFunc && Object.hasOwnProperty.call(mergeInto, prop)) { |
| 740 | mergeFrom[prop]._original = isDeferredFunc ? mergeInto[prop]._original : mergeInto[prop]; |
| 741 | } |
| 742 | // Extend recursively if both elements are objects and target is not really a deferred function |
| 743 | if (mergeFrom[prop] instanceof Date) { |
| 744 | mergeInto[prop] = mergeFrom[prop]; |
| 745 | } |
| 746 | |
| 747 | if ((mergeFrom[prop] instanceof RegExp) || |
| 748 | (mergeFrom[prop] instanceof RawConfig)) { |
| 749 | mergeInto[prop] = mergeFrom[prop]; |
| 750 | } else if (Util.isObject(mergeInto[prop]) && Util.isObject(mergeFrom[prop]) && !isDeferredFunc) { |
| 751 | Util.extendDeep(mergeInto[prop], mergeFrom[prop], depth - 1); |
| 752 | } else if (Util.isPromise(mergeFrom[prop])) { |
| 753 | mergeInto[prop] = mergeFrom[prop]; |
| 754 | } else if (mergeFrom[prop] && typeof mergeFrom[prop] === 'object') { |
| 755 | // Copy recursively if the mergeFrom element is an object (or array or fn) |
| 756 | mergeInto[prop] = Util.cloneDeep(mergeFrom[prop], depth - 1); |
| 757 | } else if (Object.getOwnPropertyDescriptor(Object(mergeFrom), prop)) { |
| 758 | // Copy property descriptor otherwise, preserving accessors |
| 759 | Object.defineProperty(mergeInto, prop, Object.getOwnPropertyDescriptor(Object(mergeFrom), prop)); |
| 760 | } else if (mergeInto[prop] !== mergeFrom[prop]) { |
| 761 | mergeInto[prop] = mergeFrom[prop]; |
| 762 | } |
| 763 | } |
| 764 | } |
| 765 | |
| 766 | // Chain |
| 767 | return mergeInto; |
| 768 | } |
| 769 | |
| 770 | /** |
| 771 | * Is the specified argument a regular javascript object? |
no test coverage detected