@@ -795,19 +795,33 @@ function copy(source, destination, stackSource, stackDest) {
795
795
796
796
if ( ! destination ) {
797
797
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.
799
808
if ( isArray ( source ) ) {
800
- destination = copy ( source , [ ] , stackSource , stackDest ) ;
809
+ return copy ( source , [ ] , stackSource , stackDest ) ;
801
810
} else if ( isTypedArray ( source ) ) {
802
811
destination = new source . constructor ( source ) ;
803
812
} else if ( isDate ( source ) ) {
804
813
destination = new Date ( source . getTime ( ) ) ;
805
814
} else if ( isRegExp ( source ) ) {
806
815
destination = new RegExp ( source . source , source . toString ( ) . match ( / [ ^ \/ ] * $ / ) [ 0 ] ) ;
807
816
destination . lastIndex = source . lastIndex ;
808
- } else if ( isObject ( source ) ) {
817
+ } else {
809
818
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 ) ;
811
825
}
812
826
}
813
827
} else {
@@ -818,9 +832,6 @@ function copy(source, destination, stackSource, stackDest) {
818
832
stackDest = stackDest || [ ] ;
819
833
820
834
if ( isObject ( source ) ) {
821
- var index = stackSource . indexOf ( source ) ;
822
- if ( index !== - 1 ) return stackDest [ index ] ;
823
-
824
835
stackSource . push ( source ) ;
825
836
stackDest . push ( destination ) ;
826
837
}
@@ -829,12 +840,7 @@ function copy(source, destination, stackSource, stackDest) {
829
840
if ( isArray ( source ) ) {
830
841
destination . length = 0 ;
831
842
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 ) ) ;
838
844
}
839
845
} else {
840
846
var h = destination . $$hashKey ;
@@ -848,37 +854,27 @@ function copy(source, destination, stackSource, stackDest) {
848
854
if ( isBlankObject ( source ) ) {
849
855
// createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
850
856
for ( key in source ) {
851
- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
857
+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
852
858
}
853
859
} else if ( source && typeof source . hasOwnProperty === 'function' ) {
854
860
// Slow path, which must rely on hasOwnProperty
855
861
for ( key in source ) {
856
862
if ( source . hasOwnProperty ( key ) ) {
857
- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
863
+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
858
864
}
859
865
}
860
866
} else {
861
867
// Slowest path --- hasOwnProperty can't be called as a method
862
868
for ( key in source ) {
863
869
if ( hasOwnProperty . call ( source , key ) ) {
864
- putValue ( key , source [ key ] , destination , stackSource , stackDest ) ;
870
+ destination [ key ] = copy ( source [ key ] , null , stackSource , stackDest ) ;
865
871
}
866
872
}
867
873
}
868
874
setHashKey ( destination , h ) ;
869
875
}
870
876
}
871
877
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
- }
882
878
}
883
879
884
880
/**
0 commit comments