Ben Meyer Structural Equality in JS
The problem of structural equality in JavaScript is that the ===
operator only checks for reference equality and not for structural equality. Ben Meyer has written a library that checks for structural equality in JavaScript. The library is called @wry/equality
and is available at:
- https://www.npmjs.com/package/@wry/equality
- https://github.com/benjamn/wryware/tree/main/packages/equality
See my notes about the library at:
To detect cycles Ben Meyer uses a map
const previousComparisons = new Map<object, Set<object>>();
and a function:
function previouslyCompared(a: object, b: object): boolean {
let bSet = previousComparisons.get(a);
if (bSet) {
if (bSet.has(b)) return true;
} else {
previousComparisons.set(a, bSet = new Set);
}
bSet.add(b);
return false;
}
which is called in the check
function that tests deep equality:
function check(a: any, b: any): boolean {
if (a === b) { return true; }
const aTag = toString.call(a); const bTag = toString.call(b);
if (aTag !== bTag) { return false; }
switch (aTag) {
case '[object Object]': {
if (previouslyCompared(a, b)) return true;
const aKeys = definedKeys(a); const bKeys = definedKeys(b);
...
}
case '[object Set]': {
if (a.size !== b.size) return false;
if (previouslyCompared(a, b)) return true;
...
}
...
}
...
}
Function equality is defined only for “native functions” that is, JS functions and not external functions written in C++ and his definition is that the two functions are equal if their .toString()
strings are equal.