如何检测对象数组中是否包含指定的对象?
如何检查嵌套对象是否存在于数组中?
哎,这个问题我太熟了!你用arr.includes(obj1)没效果完全是正常的——因为JavaScript里的对象是引用类型,includes方法只会判断数组里的元素是不是和obj1指向同一个内存地址,而不是比较它们的内容是否完全一致。哪怕两个对象的键值对一模一样,只要不是同一个引用,includes就会返回false。
下面给你几种实用的解决办法,按需选择就行:
方法一:用JSON.stringify快速比较(适合简单场景)
如果你的对象里没有函数、undefined、循环引用,而且属性顺序完全一致,这个方法最省事:
const arr = [ { "a": "asdf", "b": { "a": 2, "b": 1, "c": 4 }, "c": { "a": 0, "b": 1 } }, { "a": "xswh", "b": { "a": 4, "b": null, "c": 8 }, "c": { "a": 6, "b": 5 } } ]; const obj1 = { "a": "asdf", "b": { "a": 2, "b": 1, "c": 4 }, "c": { "a": 0, "b": 1 } }; const isExist = arr.some(item => JSON.stringify(item) === JSON.stringify(obj1)); console.log(isExist); // 输出 true
⚠️ 注意:这个方法有局限性——如果对象里有undefined、函数、Symbol,或者属性顺序不同(比如一个对象是{a:1,b:2},另一个是{b:2,a:1}),JSON.stringify的结果会不一样,导致判断错误;如果有循环引用,还会直接报错。
方法二:递归深度比较(可靠通用)
如果你的对象有嵌套结构,或者包含特殊值,自己写一个递归比较函数是最稳妥的:
function deepEqual(objA, objB) { // 先判断是否为同一引用 if (objA === objB) return true; // 排除非对象或null的情况 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { return false; } // 比较属性数量 const keysA = Object.keys(objA); const keysB = Object.keys(objB); if (keysA.length !== keysB.length) return false; // 遍历每个属性递归比较 for (const key of keysA) { if (!keysB.includes(key) || !deepEqual(objA[key], objB[key])) { return false; } } return true; } // 使用示例 const isExist = arr.some(item => deepEqual(item, obj1)); console.log(isExist); // 输出 true
这个方法能处理嵌套对象、null值、不同属性顺序的情况,也能区分对象和原始类型,比JSON.stringify靠谱得多。
方法三:用第三方库(比如Lodash)
如果你的项目已经引入了Lodash,直接用它的_.isEqual方法就行——它已经帮你处理了所有边缘情况,比如循环引用、特殊值、不同类型的比较:
const isExist = arr.some(item => _.isEqual(item, obj1));
省心又稳定,不用自己写递归函数~
内容的提问来源于stack exchange,提问作者Bandolero
相关产品推荐
相关产品推荐

