function isSpecificValue ( val ) { return val instanceof Buffer || val instanceof Date || val instanceof RegExp ? true : false ; } function cloneSpecificValue ( val ) { if ( val instanceof Buffer ) { const x = Buffer . alloc ? Buffer . alloc ( val . length ) : new Buffer ( val . length ) ; val . copy ( x ) ; return x ; } else if ( val instanceof Date ) { return new Date ( val . getTime ( ) ) ; } else if ( val instanceof RegExp ) { return new RegExp ( val ) ; } else { throw new Error ( 'Unexpected situation' ) ; } } /**
 * Recursive cloning array.
 */ function deepCloneArray ( arr ) { const clone = [ ] ; arr . forEach ( function ( item , index ) { if ( typeof item === 'object' && item !== null ) { if ( Array . isArray ( item ) ) { clone [ index ] = deepCloneArray ( item ) ; } else if ( isSpecificValue ( item ) ) { clone [ index ] = cloneSpecificValue ( item ) ; } else { clone [ index ] = deepExtend ( { } , item ) ; } } else { clone [ index ] = item ; } } ) ; return clone ; } function safeGetProperty ( object , property ) { return property === '__proto__' ? undefined : object [ property ] ; } /**
 * Extending object that entered in first argument.
 *
 * Returns extended object or false if have no target object or incorrect type.
 *
 * If you wish to clone source object (without modify it), just use empty new
 * object as first argument, like this:
 *   deepExtend({}, yourObj_1, [yourObj_N]);
 */ export const deepExtend = function ( target , ... args ) : any { if ( ! target || typeof target !== 'object' ) { return false ; } if ( args . length === 0 ) { return target ; } let val , src ; for ( const obj of args ) { if ( typeof obj !== 'object' || obj === null || Array . isArray ( obj ) ) { continue ; } for ( const key of Object . keys ( obj ) ) { src = safeGetProperty ( target , key ) ; val = safeGetProperty ( obj , key ) ; if ( val === target ) { continue ; } else if ( typeof val !== 'object' || val === null ) { target [ key ] = val ; continue ; } else if ( Array . isArray ( val ) ) { target [ key ] = deepCloneArray ( val ) ; continue ; } else if ( isSpecificValue ( val ) ) { target [ key ] = cloneSpecificValue ( val ) ; continue ; } else if ( typeof src !== 'object' || src === null || Array . isArray ( src ) ) { target [ key ] = deepExtend ( { } , val ) ; continue ; } else { target [ key ] = deepExtend ( src , val ) ; continue ; } } } return target ; } ;