在JavaScript中,直接比较两个引用类型(如Object、Array、Function等)的相等性通常只会检查它们是否是同一个对象的引用,而不是它们的内容是否相等。要比较这些类型的内容是否相等,需要手动实现深度比较的逻辑。
下面是一个简单的函数示例,用于比较两个对象(包括数组)是否深度相等。请注意,这个函数为了简化,没有处理函数类型(Function)的直接比较,因为函数的内容(如闭包内的状态)通常很难或不可能进行精确的比较。
function isDeepEqual(obj1, obj2) {
// 检查基本类型或相同引用
if (obj1 === obj2) return true;
// 检查类型是否相同
if (typeof obj1 !== typeof obj2) return false;
// 检查是否为null
if (obj1 === null || obj2 === null) return false;
// 处理日期
if (obj1 instanceof Date && obj2 instanceof Date) {
return obj1.getTime() === obj2.getTime();
}
// 处理数组或对象
if (typeof obj1 === 'object' || typeof obj1 === 'function') {
// 获取对象/数组的长度
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
// 长度必须相同
if (keys1.length !== keys2.length) return false;
// 遍历键
for (let key of keys1) {
// 检查键是否存在且值相等
if (!keys2.includes(key) || !isDeepEqual(obj1[key], obj2[key])) {
return false;
}
}
return true;
}
// 对于Function,这里简单地返回false,因为没有通用的方式来比较它们的内容
if (typeof obj1 === 'function' || typeof obj2 === 'function') {
return false;
}
// 如果不是上述类型,则视为不相等
return false;
}
// 示例
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const arr1 = [1, 2, [3, 4]];
const arr2 = [1, 2, [3, 4]];
console.log(isDeepEqual(obj1, obj2)); // true
console.log(isDeepEqual(arr1, arr2)); // true
请注意,上述函数在处理具有循环引用的对象时可能会陷入无限递归。此外,对于特殊对象(如`RegExp`、`Map`、`Set`等),你需要扩展这个函数以支持这些类型的比较。
对于函数(Function)的相等性检查,由于JavaScript中函数是引用类型,并且它们的“内容”可能包括闭包中的状态,因此通常很难或不可能进行精确的比较。在实际应用中,你可能需要根据具体情况来定义函数“相等”的含义,并相应地实现比较逻辑。