【发布时间】:2019-05-11 01:23:52
【问题描述】:
我正在比较两个对象,它们的值分别为 string、number、array 和 object。至此没有问题。当我尝试比较自引用对象时,我收到以下错误RangeError: Maximum call stack size exceeded。如果自引用对象被引用到另一个对象的同一级别,则应将它们视为相等。我的问题是如何实现它。这是我的代码:
const equalsComplex = function(value, other) {
// Get the value type
const type = Object.prototype.toString.call(value);
// If the two objects are not the same type, return false
if (type !== Object.prototype.toString.call(other)) return false;
// If items are not an object or array, return false
if (['[object Array]', '[object Object]'].indexOf(type) < 0) return false;
// Compare the length of the length of the two items
const valueLen =
type === '[object Array]' ? value.length : Object.keys(value).length;
const otherLen =
type === '[object Array]' ? other.length : Object.keys(other).length;
if (valueLen !== otherLen) return false;
// Compare two items
const compare = function(item1, item2) {
// Get the object type
const itemType = Object.prototype.toString.call(item1);
// If an object or array, compare recursively
if (['[object Array]', '[object Object]'].indexOf(itemType) >= 0) {
if (!equalsComplex(item1, item2)) return false;
}
// Otherwise, do a simple comparison
else {
// If the two items are not the same type, return false
if (itemType !== Object.prototype.toString.call(item2)) return false;
// Else if it's a function, convert to a string and compare
// Otherwise, just compare
if (itemType === '[object Function]') {
if (item1.toString() !== item2.toString()) return false;
} else {
if (item1 !== item2) return false;
}
}
};
// Compare properties
if (type === '[object Array]') {
for (let i = 0; i < valueLen; i++) {
if (compare(value[i], other[i]) === false) return false;
}
} else {
for (let key in value) {
if (value.hasOwnProperty(key)) {
if (compare(value[key], other[key]) === false) return false;
}
}
}
// If nothing failed, return true
return true;
};
const r = { a: 1 };
r.b = r;
const d = { a: 1 };
d.b = d;
console.log(
equalsComplex(
{
a: 2,
b: '2',
c: false,
g: [
{ a: { j: undefined } },
{ a: 2, b: '2', c: false, g: [{ a: { j: undefined } }] },
r
]
},
{
a: 2,
b: '2',
c: false,
g: [
{ a: { j: undefined } },
{ a: 2, b: '2', c: false, g: [{ a: { j: undefined } }] },
r
]
}
)
);
【问题讨论】:
-
您可以发送一组您已经处理/验证的值吗?
-
这将允许您停止无限递归,但您能否判断循环对象在两个参数中是否位于同一位置?
-
@Icepickle 我不太明白
-
this answer 声称 underscore.js 中的
_.isEqual()函数将执行此操作。但是,文档并没有这么说。 -
@Barmar 我还没读过那么多问题????我只是检查递归部分
标签: javascript