@@ -795,19 +795,33 @@ function copy(source, destination, stackSource, stackDest) {
795795
796796 if ( ! destination ) {
797797 destination = source ;
798- if ( source ) {
798+ if ( isObject ( source ) ) {
799+ var index ;
800+ if ( stackSource && ( index = stackSource . indexOf ( source ) ) !== - 1 ) {
801+ return stackDest [ index ] ;
802+ }
803+
804+ // TypedArray, Date and RegExp have specific copy functionality and must be
805+ // pushed onto the stack before returning.
806+ // Array and other objects create the base object and recurse to copy child
807+ // objects. The array/object will be pushed onto the stack when recursed.
799808 if ( isArray ( source ) ) {
800- destination = copy ( source , [ ] , stackSource , stackDest ) ;
809+ return copy ( source , [ ] , stackSource , stackDest ) ;
801810 } else if ( isTypedArray ( source ) ) {
802811 destination = new source . constructor ( source ) ;
803812 } else if ( isDate ( source ) ) {
804813 destination = new Date ( source . getTime ( ) ) ;
805814 } else if ( isRegExp ( source ) ) {
806815 destination = new RegExp ( source . source , source . toString ( ) . match ( / [ ^ \/ ] * $ / ) [ 0 ] ) ;
807816 destination . lastIndex = source . lastIndex ;
808- } else if ( isObject ( source ) ) {
817+ } else {
809818 var emptyObject = Object . create ( getPrototypeOf ( source ) ) ;
810- destination = copy ( source , emptyObject , stackSource , stackDest ) ;
819+ return copy ( source , emptyObject , stackSource , stackDest ) ;
820+ }
821+
822+ if ( stackDest ) {
823+ stackSource . push ( source ) ;
824+ stackDest . push ( destination ) ;
811825 }
812826 }
813827 } else {
@@ -818,9 +832,6 @@ function copy(source, destination, stackSource, stackDest) {
818832 stackDest = stackDest || [ ] ;
819833
820834 if ( isObject ( source ) ) {
821- var index = stackSource . indexOf ( source ) ;
822- if ( index !== - 1 ) return stackDest [ index ] ;
823-
824835 stackSource . push ( source ) ;
825836 stackDest . push ( destination ) ;
826837 }
@@ -829,12 +840,7 @@ function copy(source, destination, stackSource, stackDest) {
829840 if ( isArray ( source ) ) {
830841 destination . length = 0 ;
831842 for ( var i = 0 ; i < source . length ; i ++ ) {
832- result = copy ( source [ i ] , null , stackSource , stackDest ) ;
833- if ( isObject ( source [ i ] ) ) {
834- stackSource . push ( source [ i ] ) ;
835- stackDest . push ( result ) ;
836- }
837- destination . push ( result ) ;
843+ destination . push ( copy ( source [ i ] , null , stackSource , stackDest ) ) ;
838844 }
839845 } else {
840846 var h = destination . $$hashKey ;
@@ -848,37 +854,27 @@ function copy(source, destination, stackSource, stackDest) {
848854 if ( isBlankObject ( source ) ) {
849855 // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
850856 for ( key in source ) {
851- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
857+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
852858 }
853859 } else if ( source && typeof source . hasOwnProperty === 'function' ) {
854860 // Slow path, which must rely on hasOwnProperty
855861 for ( key in source ) {
856862 if ( source . hasOwnProperty ( key ) ) {
857- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
863+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
858864 }
859865 }
860866 } else {
861867 // Slowest path --- hasOwnProperty can't be called as a method
862868 for ( key in source ) {
863869 if ( hasOwnProperty . call ( source , key ) ) {
864- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
870+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
865871 }
866872 }
867873 }
868874 setHashKey ( destination , h ) ;
869875 }
870876 }
871877 return destination ;
872-
873- function putValue ( key , val , destination , stackSource , stackDest ) {
874- // No context allocation, trivial outer scope, easily inlined
875- var result = copy ( val , null , stackSource , stackDest ) ;
876- if ( isObject ( val ) ) {
877- stackSource . push ( val ) ;
878- stackDest . push ( result ) ;
879- }
880- destination [ key ] = result ;
881- }
882878}
883879
884880/**
0 commit comments