@@ -743,19 +743,33 @@ function copy(source, destination, stackSource, stackDest) {
743
743
744
744
if ( ! destination ) {
745
745
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.
747
756
if ( isArray ( source ) ) {
748
- destination = copy ( source , [ ] , stackSource , stackDest ) ;
757
+ return copy ( source , [ ] , stackSource , stackDest ) ;
749
758
} else if ( isTypedArray ( source ) ) {
750
759
destination = new source . constructor ( source ) ;
751
760
} else if ( isDate ( source ) ) {
752
761
destination = new Date ( source . getTime ( ) ) ;
753
762
} else if ( isRegExp ( source ) ) {
754
763
destination = new RegExp ( source . source , source . toString ( ) . match ( / [ ^ \/ ] * $ / ) [ 0 ] ) ;
755
764
destination . lastIndex = source . lastIndex ;
756
- } else if ( isObject ( source ) ) {
765
+ } else {
757
766
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 ) ;
759
773
}
760
774
}
761
775
} else {
@@ -766,9 +780,6 @@ function copy(source, destination, stackSource, stackDest) {
766
780
stackDest = stackDest || [ ] ;
767
781
768
782
if ( isObject ( source ) ) {
769
- var index = stackSource . indexOf ( source ) ;
770
- if ( index !== - 1 ) return stackDest [ index ] ;
771
-
772
783
stackSource . push ( source ) ;
773
784
stackDest . push ( destination ) ;
774
785
}
@@ -777,12 +788,7 @@ function copy(source, destination, stackSource, stackDest) {
777
788
if ( isArray ( source ) ) {
778
789
destination . length = 0 ;
779
790
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 ) ) ;
786
792
}
787
793
} else {
788
794
var h = destination . $$hashKey ;
@@ -796,37 +802,27 @@ function copy(source, destination, stackSource, stackDest) {
796
802
if ( isBlankObject ( source ) ) {
797
803
// createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
798
804
for ( key in source ) {
799
- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
805
+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
800
806
}
801
807
} else if ( source && typeof source . hasOwnProperty === 'function' ) {
802
808
// Slow path, which must rely on hasOwnProperty
803
809
for ( key in source ) {
804
810
if ( source . hasOwnProperty ( key ) ) {
805
- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
811
+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
806
812
}
807
813
}
808
814
} else {
809
815
// Slowest path --- hasOwnProperty can't be called as a method
810
816
for ( key in source ) {
811
817
if ( hasOwnProperty . call ( source , key ) ) {
812
- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
818
+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
813
819
}
814
820
}
815
821
}
816
822
setHashKey ( destination , h ) ;
817
823
}
818
824
}
819
825
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
- }
830
826
}
831
827
832
828
/**
0 commit comments