我正在实现一个函数,它比较两个 JavaScript 对象的“深度”相等性。现在,这个函数的骨架如下所示:
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 {
// ??? cyclic reference detected
}
}
check_equal_r(act, exp);
}
问题是在它所说的地方放什么// ??? cyclic reference detected
。理想情况下,我想说这些对象是深度相等的:
var a = {foo:1, bar:2, baz:null},
b = {foo:1, bar:2, baz:null};
a.baz = a;
b.baz = b;
并且这些对象不是深度相等的:
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;
笔记:
assert
如果其参数为假,则抛出异常。have_all_the_same_properties(x, y)
如果和的getOwnPropertyNames
列表不相同,则抛出异常。x
y
is_scalar(x)
实际上与相同typeof x !== 'object'
。- 为了简洁起见,我在上面的代码中使用了 for-of 循环,但是 ES6 功能在实际运行的解释器中不可用。