@@ -10,6 +10,7 @@ import {
10
10
isPlainObject ,
11
11
objToStr ,
12
12
deepEqualsMethod ,
13
+ DeepEqualsHelper ,
13
14
} from "./helpers" ;
14
15
15
16
type Checker < T > = (
@@ -50,12 +51,20 @@ const CHECKERS_BY_TAG = new Map<string, Checker<any>>()
50
51
. set ( '[object AsyncGeneratorFunction]' , checkFunctions )
51
52
. set ( '[object Function]' , checkFunctions ) ;
52
53
54
+ function getBoundCheck ( checker : DeepChecker ) : DeepEqualsHelper {
55
+ return checker [ "boundCheck" ] || ( checker [ "boundCheck" ] = function ( a , b ) {
56
+ return checker . check ( a , b ) ;
57
+ } ) ;
58
+ }
59
+
53
60
export class DeepChecker {
54
- private comparisons = new Trie < {
55
- equal ?: boolean ;
56
- } > ( false ) ;
61
+ // Initialized lazily because not always needed.
62
+ private comparisons : null | Trie < { equal ?: boolean ; } > = null ;
63
+
64
+ // Initialized lazily because needed only when custom deepEqualsMethod methods
65
+ // are in use.
66
+ private boundCheck : null | DeepEqualsHelper = null ;
57
67
58
- public readonly boundCheck : DeepChecker [ "check" ] = ( a , b ) => this . check ( a , b ) ;
59
68
public check ( a : any , b : any ) : boolean {
60
69
// If the two values are strictly equal, our job is easy.
61
70
if ( a === b ) {
@@ -80,7 +89,9 @@ export class DeepChecker {
80
89
81
90
const found =
82
91
bothNonNullObjects &&
83
- this . comparisons . lookup ( a , b ) ;
92
+ ( this . comparisons || (
93
+ this . comparisons = new Trie ( false )
94
+ ) ) . lookup ( a , b ) ;
84
95
85
96
// Though cyclic references can make an object graph appear infinite from
86
97
// the perspective of a depth-first traversal, the graph still contains a
@@ -122,15 +133,15 @@ function tryEqualsMethod(checker: DeepChecker, a: any, b: any): boolean {
122
133
return (
123
134
isEquatable ( checker , a ) &&
124
135
isEquatable ( checker , b ) &&
125
- a [ deepEqualsMethod ] ( b , checker . boundCheck ) &&
136
+ a [ deepEqualsMethod ] ( b , getBoundCheck ( checker ) ) &&
126
137
// Verify symmetry. If a[deepEqualsMethod] is not exactly the same function
127
138
// as b[deepEqualsMethod], b[deepEqualsMethod](a) can legitimately disagree
128
139
// with a[deepEqualsMethod](b), so we must check both. However, in the
129
140
// common case where a[deepEqualsMethod] === b[deepEqualsMethod], the
130
141
// additional check should be redundant, unless that method is itself
131
142
// somehow non-commutative/asymmetric.
132
143
( a [ deepEqualsMethod ] === b [ deepEqualsMethod ] ||
133
- b [ deepEqualsMethod ] ( a , checker . boundCheck ) )
144
+ b [ deepEqualsMethod ] ( a , getBoundCheck ( checker ) ) )
134
145
) ;
135
146
}
136
147
0 commit comments