I am implementing a function that compares two JavaScript objects for "deep" equality. The skeleton of this function now looks like this:
function check_equal(actual, expected) { var stack = []; function check_equal_r(act, exp) { if (is_scalar(act) || is_scalar(exp)) { assert(act === exp); } else if (stack.indexOf(act) == -1) { assert(have_all_the_same_properties(act, exp)); stack.push(act); for (var k of Object.getOwnPropertyNames(exp)) { check_equal_r(act[k], exp[k]); } stack.pop(act); } else {
The question is what to put where it says // ??? cyclic reference detected // ??? cyclic reference detected . Ideally, I would like to say that these objects are deep:
var a = {foo:1, bar:2, baz:null}, b = {foo:1, bar:2, baz:null}; a.baz = a; b.baz = b;
and these objects are not deep:
var a = { car: 1, cdr: { car: 2, cdr: null } }; var b = { car: 1, cdr: { car: 2, cdr: null } }; a.cdr.cdr = a; b.cdr.cdr = b.cdr;
Notes:
assert throws an exception if its argument is false.have_all_the_same_properties(x, y) throws an exception if the getOwnPropertyNames x and y lists getOwnPropertyNames not identical.is_scalar(x) actually matches typeof x !== 'object' .- I used the for loop in the loop above for brevity, but ES6 functions are not available in the interpreter, this will actually execute.
source share