@@ -267,9 +267,16 @@ function forEach(obj, iterator, context) {
267
267
}
268
268
} else if ( obj . forEach && obj . forEach !== forEach ) {
269
269
obj . forEach ( iterator , context , obj ) ;
270
+ } else if ( isObject ( obj ) && ! Object . getPrototypeOf ( obj ) ) {
271
+ // Fast path for createMap()
272
+ for ( key in obj ) {
273
+ iterator . call ( context , obj [ key ] , key , obj ) ;
274
+ }
270
275
} else {
276
+ // Slow path for ordinary objects
277
+ var hasOwn = typeof obj . hasOwnProperty === 'function' ;
271
278
for ( key in obj ) {
272
- if ( obj . hasOwnProperty ( key ) ) {
279
+ if ( hasOwn ? obj . hasOwnProperty ( key ) : hasOwnProperty . call ( obj , key ) ) {
273
280
iterator . call ( context , obj [ key ] , key , obj ) ;
274
281
}
275
282
}
@@ -820,14 +827,29 @@ function copy(source, destination, stackSource, stackDest) {
820
827
delete destination [ key ] ;
821
828
} ) ;
822
829
}
823
- for ( var key in source ) {
824
- if ( source . hasOwnProperty ( key ) ) {
825
- result = copy ( source [ key ] , null , stackSource , stackDest ) ;
826
- if ( isObject ( source [ key ] ) ) {
827
- stackSource . push ( source [ key ] ) ;
830
+ if ( isObject ( source ) && ! Object . getPrototypeOf ( source ) ) {
831
+ // createMap() fast path
832
+ for ( var key in source ) {
833
+ var val = source [ key ] ;
834
+ result = copy ( val , null , stackSource , stackDest ) ;
835
+ if ( isObject ( val ) ) {
836
+ stackSource . push ( val ) ;
828
837
stackDest . push ( result ) ;
829
838
}
830
- destination [ key ] = result ;
839
+ }
840
+ } else {
841
+ // Slow path, which must rely on hasOwnProperty
842
+ var hasOwn = source && typeof source . hasOwnProperty === 'function' ;
843
+ for ( var key in source ) {
844
+ if ( hasOwn ? source . hasOwnProperty ( key ) : hasOwnProperty . call ( source , key ) ) {
845
+ var val = source [ key ] ;
846
+ result = copy ( val , null , stackSource , stackDest ) ;
847
+ if ( isObject ( val ) ) {
848
+ stackSource . push ( val ) ;
849
+ stackDest . push ( result ) ;
850
+ }
851
+ destination [ key ] = result ;
852
+ }
831
853
}
832
854
}
833
855
setHashKey ( destination , h ) ;
@@ -915,14 +937,14 @@ function equals(o1, o2) {
915
937
} else {
916
938
if ( isScope ( o1 ) || isScope ( o2 ) || isWindow ( o1 ) || isWindow ( o2 ) ||
917
939
isArray ( o2 ) || isDate ( o2 ) || isRegExp ( o2 ) ) return false ;
918
- keySet = { } ;
940
+ keySet = createMap ( ) ;
919
941
for ( key in o1 ) {
920
942
if ( key . charAt ( 0 ) === '$' || isFunction ( o1 [ key ] ) ) continue ;
921
943
if ( ! equals ( o1 [ key ] , o2 [ key ] ) ) return false ;
922
944
keySet [ key ] = true ;
923
945
}
924
946
for ( key in o2 ) {
925
- if ( ! keySet . hasOwnProperty ( key ) &&
947
+ if ( ! ( key in keySet ) &&
926
948
key . charAt ( 0 ) !== '$' &&
927
949
o2 [ key ] !== undefined &&
928
950
! isFunction ( o2 [ key ] ) ) return false ;
0 commit comments