function isApproxEqual(x, y, opts) {
  opts = opts || {};
  var fnEqual = opts.fnEqual !== false;
  var depth = opts.depth || 5; // totally arbitrary

  // state contains pairs we checked (or are still checking, but assume equal!)
  var state = [];

  function loop(a, b, n) {
    if (isNaN(a) && isNaN(b)) {
      return true;
    }

    // trivial check
    if (a === b) {
      return true;
    }

    // depth check
    if (n >= depth) {
      return true;
    }

    var i;

    // check if pair already occured
    for (i = 0; i < state.length; i++) {
      if (state[i][0] === a && state[i][1] === b) {
        return true;
      }
    }

    // add to state
    state.push([a, b]);

    if (typeof a === "function" && typeof b === "function") {
      return fnEqual;
    }

    if (isArray(a) && isArray(b) && a.length === b.length) {
      for (i = 0; i < a.length; i++) {
        if (!loop(a[i], b[i], n + 1)) {
          return false;
        }
      }
      return true;
    } else if (isObject(a) && isObject(b) && !isArray(a) && !isArray(b)) {
      var akeys = Object.keys(a);
      var bkeys = Object.keys(b);
      if (!loop(sort(akeys), sort(bkeys), n + 1)) {
        return false;
      }

      for (i = 0; i < akeys.length; i++) {
        if (!loop(a[akeys[i]], b[akeys[i]], n + 1)) {
          return false;
        }
      }
      return true;
    }

    return false;
  }
  return loop(x, y, 0);
}
- `utils.isApproxEqual(x: a, y: b, opts: obj): bool`

      Tests whether two objects are approximately and optimistically equal.
      Returns `false` only if they are distinguishable not equal.
      Returns `true` when `x` and `y` are `NaN`.
      This function works with cyclic data.

      Takes optional 'opts' parameter with properties:

      - `fnEqual` - whether all functions are considered equal (default: yes)
      - `depth` - how deep to recurse until treating as equal (default: 5)