TopicsextendingjsStructural Equality

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:

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.