@@ -14,7 +14,9 @@ const {
14
14
isStringObject,
15
15
isBooleanObject,
16
16
isBigIntObject,
17
- isSymbolObject
17
+ isSymbolObject,
18
+ isFloat32Array,
19
+ isFloat64Array
18
20
} = require ( 'internal/util/types' ) ;
19
21
const {
20
22
getOwnNonIndexProperties,
@@ -84,18 +86,6 @@ function areEqualArrayBuffers(buf1, buf2) {
84
86
compare ( new Uint8Array ( buf1 ) , new Uint8Array ( buf2 ) ) === 0 ;
85
87
}
86
88
87
- function isFloatTypedArrayTag ( tag ) {
88
- return tag === '[object Float32Array]' || tag === '[object Float64Array]' ;
89
- }
90
-
91
- function isArguments ( tag ) {
92
- return tag === '[object Arguments]' ;
93
- }
94
-
95
- function isObjectOrArrayTag ( tag ) {
96
- return tag === '[object Array]' || tag === '[object Object]' ;
97
- }
98
-
99
89
function isEqualBoxedPrimitive ( val1 , val2 ) {
100
90
if ( isNumberObject ( val1 ) ) {
101
91
return isNumberObject ( val2 ) &&
@@ -132,23 +122,45 @@ function isEqualBoxedPrimitive(val1, val2) {
132
122
// For strict comparison, objects should have
133
123
// a) The same built-in type tags
134
124
// b) The same prototypes.
135
- function strictDeepEqual ( val1 , val2 , memos ) {
136
- if ( typeof val1 !== 'object' ) {
137
- return typeof val1 === 'number' && numberIsNaN ( val1 ) &&
138
- numberIsNaN ( val2 ) ;
125
+
126
+ function innerDeepEqual ( val1 , val2 , strict , memos ) {
127
+ // All identical values are equivalent, as determined by ===.
128
+ if ( val1 === val2 ) {
129
+ if ( val1 !== 0 )
130
+ return true ;
131
+ return strict ? objectIs ( val1 , val2 ) : true ;
139
132
}
140
- if ( typeof val2 !== 'object' || val1 === null || val2 === null ) {
141
- return false ;
133
+
134
+ // Check more closely if val1 and val2 are equal.
135
+ if ( strict ) {
136
+ if ( typeof val1 !== 'object' ) {
137
+ return typeof val1 === 'number' && numberIsNaN ( val1 ) &&
138
+ numberIsNaN ( val2 ) ;
139
+ }
140
+ if ( typeof val2 !== 'object' || val1 === null || val2 === null ) {
141
+ return false ;
142
+ }
143
+ if ( getPrototypeOf ( val1 ) !== getPrototypeOf ( val2 ) ) {
144
+ return false ;
145
+ }
146
+ } else {
147
+ if ( val1 === null || typeof val1 !== 'object' ) {
148
+ if ( val2 === null || typeof val2 !== 'object' ) {
149
+ // eslint-disable-next-line eqeqeq
150
+ return val1 == val2 ;
151
+ }
152
+ return false ;
153
+ }
154
+ if ( val2 === null || typeof val2 !== 'object' ) {
155
+ return false ;
156
+ }
142
157
}
143
158
const val1Tag = objectToString ( val1 ) ;
144
159
const val2Tag = objectToString ( val2 ) ;
145
160
146
161
if ( val1Tag !== val2Tag ) {
147
162
return false ;
148
163
}
149
- if ( getPrototypeOf ( val1 ) !== getPrototypeOf ( val2 ) ) {
150
- return false ;
151
- }
152
164
if ( Array . isArray ( val1 ) ) {
153
165
// Check for sparse arrays and general fast path
154
166
if ( val1 . length !== val2 . length ) {
@@ -159,10 +171,10 @@ function strictDeepEqual(val1, val2, memos) {
159
171
if ( keys1 . length !== keys2 . length ) {
160
172
return false ;
161
173
}
162
- return keyCheck ( val1 , val2 , kStrict , memos , kIsArray , keys1 ) ;
174
+ return keyCheck ( val1 , val2 , strict , memos , kIsArray , keys1 ) ;
163
175
}
164
176
if ( val1Tag === '[object Object]' ) {
165
- return keyCheck ( val1 , val2 , kStrict , memos , kNoIterator ) ;
177
+ return keyCheck ( val1 , val2 , strict , memos , kNoIterator ) ;
166
178
}
167
179
if ( isDate ( val1 ) ) {
168
180
if ( dateGetTime ( val1 ) !== dateGetTime ( val2 ) ) {
@@ -174,13 +186,16 @@ function strictDeepEqual(val1, val2, memos) {
174
186
}
175
187
} else if ( isNativeError ( val1 ) || val1 instanceof Error ) {
176
188
// Do not compare the stack as it might differ even though the error itself
177
- // is otherwise identical. The non-enumerable name should be identical as
178
- // the prototype is also identical. Otherwise this is caught later on.
179
- if ( val1 . message !== val2 . message ) {
189
+ // is otherwise identical.
190
+ if ( val1 . message !== val2 . message || val1 . name !== val2 . name ) {
180
191
return false ;
181
192
}
182
193
} else if ( isArrayBufferView ( val1 ) ) {
183
- if ( ! areSimilarTypedArrays ( val1 , val2 ) ) {
194
+ if ( ! strict && ( isFloat32Array ( val1 ) || isFloat64Array ( val1 ) ) ) {
195
+ if ( ! areSimilarFloatArrays ( val1 , val2 ) ) {
196
+ return false ;
197
+ }
198
+ } else if ( ! areSimilarTypedArrays ( val1 , val2 ) ) {
184
199
return false ;
185
200
}
186
201
// Buffer.compare returns true, so val1.length === val2.length. If they both
@@ -191,84 +206,25 @@ function strictDeepEqual(val1, val2, memos) {
191
206
if ( keys1 . length !== keys2 . length ) {
192
207
return false ;
193
208
}
194
- return keyCheck ( val1 , val2 , kStrict , memos , kNoIterator , keys1 ) ;
209
+ return keyCheck ( val1 , val2 , strict , memos , kNoIterator , keys1 ) ;
195
210
} else if ( isSet ( val1 ) ) {
196
211
if ( ! isSet ( val2 ) || val1 . size !== val2 . size ) {
197
212
return false ;
198
213
}
199
- return keyCheck ( val1 , val2 , kStrict , memos , kIsSet ) ;
214
+ return keyCheck ( val1 , val2 , strict , memos , kIsSet ) ;
200
215
} else if ( isMap ( val1 ) ) {
201
216
if ( ! isMap ( val2 ) || val1 . size !== val2 . size ) {
202
217
return false ;
203
218
}
204
- return keyCheck ( val1 , val2 , kStrict , memos , kIsMap ) ;
219
+ return keyCheck ( val1 , val2 , strict , memos , kIsMap ) ;
205
220
} else if ( isAnyArrayBuffer ( val1 ) ) {
206
221
if ( ! areEqualArrayBuffers ( val1 , val2 ) ) {
207
222
return false ;
208
223
}
209
224
} else if ( isBoxedPrimitive ( val1 ) && ! isEqualBoxedPrimitive ( val1 , val2 ) ) {
210
225
return false ;
211
226
}
212
- return keyCheck ( val1 , val2 , kStrict , memos , kNoIterator ) ;
213
- }
214
-
215
- function looseDeepEqual ( val1 , val2 , memos ) {
216
- if ( val1 === null || typeof val1 !== 'object' ) {
217
- if ( val2 === null || typeof val2 !== 'object' ) {
218
- // eslint-disable-next-line eqeqeq
219
- return val1 == val2 ;
220
- }
221
- return false ;
222
- }
223
- if ( val2 === null || typeof val2 !== 'object' ) {
224
- return false ;
225
- }
226
- const val1Tag = objectToString ( val1 ) ;
227
- const val2Tag = objectToString ( val2 ) ;
228
- if ( val1Tag === val2Tag ) {
229
- if ( isObjectOrArrayTag ( val1Tag ) ) {
230
- return keyCheck ( val1 , val2 , kLoose , memos , kNoIterator ) ;
231
- }
232
- if ( isArrayBufferView ( val1 ) ) {
233
- if ( isFloatTypedArrayTag ( val1Tag ) ) {
234
- return areSimilarFloatArrays ( val1 , val2 ) ;
235
- }
236
- return areSimilarTypedArrays ( val1 , val2 ) ;
237
- }
238
- if ( isDate ( val1 ) && isDate ( val2 ) ) {
239
- return val1 . getTime ( ) === val2 . getTime ( ) ;
240
- }
241
- if ( isRegExp ( val1 ) && isRegExp ( val2 ) ) {
242
- return areSimilarRegExps ( val1 , val2 ) ;
243
- }
244
- if ( val1 instanceof Error && val2 instanceof Error ) {
245
- if ( val1 . message !== val2 . message || val1 . name !== val2 . name )
246
- return false ;
247
- }
248
- // Ensure reflexivity of deepEqual with `arguments` objects.
249
- // See https://github.com/nodejs/node-v0.x-archive/pull/7178
250
- } else if ( isArguments ( val1Tag ) || isArguments ( val2Tag ) ) {
251
- return false ;
252
- }
253
- if ( isSet ( val1 ) ) {
254
- if ( ! isSet ( val2 ) || val1 . size !== val2 . size ) {
255
- return false ;
256
- }
257
- return keyCheck ( val1 , val2 , kLoose , memos , kIsSet ) ;
258
- } else if ( isMap ( val1 ) ) {
259
- if ( ! isMap ( val2 ) || val1 . size !== val2 . size ) {
260
- return false ;
261
- }
262
- return keyCheck ( val1 , val2 , kLoose , memos , kIsMap ) ;
263
- } else if ( isSet ( val2 ) || isMap ( val2 ) ) {
264
- return false ;
265
- }
266
- if ( isAnyArrayBuffer ( val1 ) && isAnyArrayBuffer ( val2 ) ) {
267
- if ( ! areEqualArrayBuffers ( val1 , val2 ) ) {
268
- return false ;
269
- }
270
- }
271
- return keyCheck ( val1 , val2 , kLoose , memos , kNoIterator ) ;
227
+ return keyCheck ( val1 , val2 , strict , memos , kNoIterator ) ;
272
228
}
273
229
274
230
function getEnumerables ( val , keys ) {
@@ -370,21 +326,6 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
370
326
return areEq ;
371
327
}
372
328
373
- function innerDeepEqual ( val1 , val2 , strict , memos ) {
374
- // All identical values are equivalent, as determined by ===.
375
- if ( val1 === val2 ) {
376
- if ( val1 !== 0 )
377
- return true ;
378
- return strict ? objectIs ( val1 , val2 ) : true ;
379
- }
380
-
381
- // Check more closely if val1 and val2 are equal.
382
- if ( strict === true )
383
- return strictDeepEqual ( val1 , val2 , memos ) ;
384
-
385
- return looseDeepEqual ( val1 , val2 , memos ) ;
386
- }
387
-
388
329
function setHasEqualElement ( set , val1 , strict , memo ) {
389
330
// Go looking.
390
331
for ( const val2 of set ) {
0 commit comments