@@ -743,19 +743,33 @@ function copy(source, destination, stackSource, stackDest) {
743743
744744 if ( ! destination ) {
745745 destination = source ;
746- if ( source ) {
746+ if ( isObject ( source ) ) {
747+ var index ;
748+ if ( stackSource && ( index = stackSource . indexOf ( source ) ) !== - 1 ) {
749+ return stackDest [ index ] ;
750+ }
751+
752+ // TypedArray, Date and RegExp have specific copy functionality and must be
753+ // pushed onto the stack before returning.
754+ // Array and other objects create the base object and recurse to copy child
755+ // objects. The array/object will be pushed onto the stack when recursed.
747756 if ( isArray ( source ) ) {
748- destination = copy ( source , [ ] , stackSource , stackDest ) ;
757+ return copy ( source , [ ] , stackSource , stackDest ) ;
749758 } else if ( isTypedArray ( source ) ) {
750759 destination = new source . constructor ( source ) ;
751760 } else if ( isDate ( source ) ) {
752761 destination = new Date ( source . getTime ( ) ) ;
753762 } else if ( isRegExp ( source ) ) {
754763 destination = new RegExp ( source . source , source . toString ( ) . match ( / [ ^ \/ ] * $ / ) [ 0 ] ) ;
755764 destination . lastIndex = source . lastIndex ;
756- } else if ( isObject ( source ) ) {
765+ } else {
757766 var emptyObject = Object . create ( getPrototypeOf ( source ) ) ;
758- destination = copy ( source , emptyObject , stackSource , stackDest ) ;
767+ return copy ( source , emptyObject , stackSource , stackDest ) ;
768+ }
769+
770+ if ( stackDest ) {
771+ stackSource . push ( source ) ;
772+ stackDest . push ( destination ) ;
759773 }
760774 }
761775 } else {
@@ -766,9 +780,6 @@ function copy(source, destination, stackSource, stackDest) {
766780 stackDest = stackDest || [ ] ;
767781
768782 if ( isObject ( source ) ) {
769- var index = stackSource . indexOf ( source ) ;
770- if ( index !== - 1 ) return stackDest [ index ] ;
771-
772783 stackSource . push ( source ) ;
773784 stackDest . push ( destination ) ;
774785 }
@@ -777,12 +788,7 @@ function copy(source, destination, stackSource, stackDest) {
777788 if ( isArray ( source ) ) {
778789 destination . length = 0 ;
779790 for ( var i = 0 ; i < source . length ; i ++ ) {
780- result = copy ( source [ i ] , null , stackSource , stackDest ) ;
781- if ( isObject ( source [ i ] ) ) {
782- stackSource . push ( source [ i ] ) ;
783- stackDest . push ( result ) ;
784- }
785- destination . push ( result ) ;
791+ destination . push ( copy ( source [ i ] , null , stackSource , stackDest ) ) ;
786792 }
787793 } else {
788794 var h = destination . $$hashKey ;
@@ -796,37 +802,27 @@ function copy(source, destination, stackSource, stackDest) {
796802 if ( isBlankObject ( source ) ) {
797803 // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
798804 for ( key in source ) {
799- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
805+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
800806 }
801807 } else if ( source && typeof source . hasOwnProperty === 'function' ) {
802808 // Slow path, which must rely on hasOwnProperty
803809 for ( key in source ) {
804810 if ( source . hasOwnProperty ( key ) ) {
805- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
811+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
806812 }
807813 }
808814 } else {
809815 // Slowest path --- hasOwnProperty can't be called as a method
810816 for ( key in source ) {
811817 if ( hasOwnProperty . call ( source , key ) ) {
812- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
818+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
813819 }
814820 }
815821 }
816822 setHashKey ( destination , h ) ;
817823 }
818824 }
819825 return destination ;
820-
821- function putValue ( key , val , destination , stackSource , stackDest ) {
822- // No context allocation, trivial outer scope, easily inlined
823- var result = copy ( val , null , stackSource , stackDest ) ;
824- if ( isObject ( val ) ) {
825- stackSource . push ( val ) ;
826- stackDest . push ( result ) ;
827- }
828- destination [ key ] = result ;
829- }
830826}
831827
832828/**
0 commit comments