js对象如何深比较?
JavaScript 对象的深比较几种常见方法:
1. 使用 JSON.stringify:
这是最简单的方法之一,但有一些限制。它将对象转换为字符串进行比较,因此无法处理循环引用,并且会忽略函数和 undefined 值。
function deepEqual(obj1, obj2) {
return JSON.stringify(obj1) === JSON.stringify(obj2);
}
let obj1 = { a: 1, b: '2' };
let obj2 = { a: 1, b: '2' };
let obj3 = { b: '2', a: 1 }; // 即使属性顺序不同,也认为是相等的
console.log(deepEqual(obj1, obj2)); // true
console.log(deepEqual(obj1, obj3)); // true
let obj4 = { a: 1, b: 2 };
console.log(deepEqual(obj1, obj4)); // false
// limitations
let obj5 = { a: 1, b: undefined };
let obj6 = { a: 1 };
console.log(deepEqual(obj5, obj6)); // false undefined会被忽略
let obj7 = { a: function() {} };
let obj8 = { a: function() {} };
console.log(deepEqual(obj7, obj8)); // false 函数会被忽略
2. 递归比较:
这是更稳健的方法,可以处理各种数据类型,包括嵌套对象、数组和函数。
function deepEqual(obj1, obj2) {
if (typeof obj1 !== typeof obj2) return false;
if (typeof obj1 === 'object') {
if (Array.isArray(obj1)) {
if (!Array.isArray(obj2) || obj1.length !== obj2.length) return false;
for (let i = 0; i < obj1.length; i++) {
if (!deepEqual(obj1[i], obj2[i])) return false;
}
return true;
} else {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
for (const key of keys1) {
if (!obj2.hasOwnProperty(key) || !deepEqual(obj1[key], obj2[key])) return false;
}
return true;
}
} else if (typeof obj1 === 'function') {
// 比较函数通常比较复杂,可以比较函数的toString(),但并不完全可靠
return obj1.toString() === obj2.toString();
} else {
return obj1 === obj2;
}
}
let obj1 = { a: 1, b: { c: 3 } };
let obj2 = { a: 1, b: { c: 3 } };
console.log(deepEqual(obj1, obj2)); // true
let obj3 = { a: 1, b: { c: 4 } };
console.log(deepEqual(obj1, obj3)); // false
let arr1 = [1, 2, { a: 1 }];
let arr2 = [1, 2, { a: 1 }];
console.log(deepEqual(arr1, arr2)); // true
3. 使用 Lodash 的 _.isEqual
:
Lodash 是一个流行的 JavaScript 实用工具库,提供了一个 _.isEqual
函数,可以进行深度比较。它处理各种边缘情况,包括循环引用。
const _ = require('lodash');
let obj1 = { a: 1, b: { c: 3 } };
let obj2 = { a: 1, b: { c: 3 } };
console.log(_.isEqual(obj1, obj2)); // true
let obj3 = { a: 1, b: { c: 4 } };
console.log(_.isEqual(obj1, obj3)); // false
// 处理循环引用
let obj4 = {};
obj4.a = obj4;
let obj5 = {};
obj5.a = obj5;
console.log(_.isEqual(obj4, obj5)); // true
选择哪种方法?
- 对于简单的对象比较,
JSON.stringify
可能足够。 - 对于更复杂的情况,递归方法提供更大的控制力和灵活性。
- 对于需要处理循环引用或其他边缘情况的生产
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!