Skip to content

Commit 0d2002a

Browse files
committed
Initialize members lazily to cheapen DeepChecker constructor.
1 parent a50167e commit 0d2002a

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

packages/equality/src/checker.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
isPlainObject,
1111
objToStr,
1212
deepEqualsMethod,
13+
DeepEqualsHelper,
1314
} from "./helpers";
1415

1516
type Checker<T> = (
@@ -50,12 +51,20 @@ const CHECKERS_BY_TAG = new Map<string, Checker<any>>()
5051
.set('[object AsyncGeneratorFunction]', checkFunctions)
5152
.set('[object Function]', checkFunctions);
5253

54+
function getBoundCheck(checker: DeepChecker): DeepEqualsHelper {
55+
return checker["boundCheck"] || (checker["boundCheck"] = function (a, b) {
56+
return checker.check(a, b);
57+
});
58+
}
59+
5360
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;
5767

58-
public readonly boundCheck: DeepChecker["check"] = (a, b) => this.check(a, b);
5968
public check(a: any, b: any): boolean {
6069
// If the two values are strictly equal, our job is easy.
6170
if (a === b) {
@@ -80,7 +89,9 @@ export class DeepChecker {
8089

8190
const found =
8291
bothNonNullObjects &&
83-
this.comparisons.lookup(a, b);
92+
(this.comparisons || (
93+
this.comparisons = new Trie(false)
94+
)).lookup(a, b);
8495

8596
// Though cyclic references can make an object graph appear infinite from
8697
// 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 {
122133
return (
123134
isEquatable(checker, a) &&
124135
isEquatable(checker, b) &&
125-
a[deepEqualsMethod](b, checker.boundCheck) &&
136+
a[deepEqualsMethod](b, getBoundCheck(checker)) &&
126137
// Verify symmetry. If a[deepEqualsMethod] is not exactly the same function
127138
// as b[deepEqualsMethod], b[deepEqualsMethod](a) can legitimately disagree
128139
// with a[deepEqualsMethod](b), so we must check both. However, in the
129140
// common case where a[deepEqualsMethod] === b[deepEqualsMethod], the
130141
// additional check should be redundant, unless that method is itself
131142
// somehow non-commutative/asymmetric.
132143
(a[deepEqualsMethod] === b[deepEqualsMethod] ||
133-
b[deepEqualsMethod](a, checker.boundCheck))
144+
b[deepEqualsMethod](a, getBoundCheck(checker)))
134145
);
135146
}
136147

0 commit comments

Comments
 (0)