arr.includes()无法匹配数组中新创建的JSON对象问题咨询
为什么
Array.includes()对新创建的对象返回false? 这是个非常典型的JavaScript引用类型比较问题,我来给你掰扯清楚~
首先得明确:JavaScript里的对象是引用类型,不是值类型。当你写{id:2,name:'a'}的时候,每次执行这段代码都会在内存里创建一个全新的对象,拥有独立的内存地址。而Array.includes()方法判断元素是否存在时,用的是严格相等运算符(===)——它比较的不是对象的内容,而是两个值是否指向同一个内存地址。
看你的代码例子:
const b = [{id:2,name:'a'},{id:3,name:'b'}]; b.includes({id:2,name:'a'}); // false b.includes(b[0]); // true
- 第一个调用里的
{id:2,name:'a'}是新创建的对象,和数组里的b[0]虽然内容完全一样,但内存地址完全不同,所以===返回false,includes()也就跟着返回false。 - 第二个调用里的
b[0]就是数组里的那个对象本身,和数组里的元素是同一个引用,所以===返回true,includes()自然返回true。
那怎么检查数组里是否存在属性匹配的对象?
如果你想判断数组里有没有内容匹配的对象,应该用Array.prototype.some()方法,它允许你自定义判断逻辑:
简单场景:直接比较属性
const b = [{id:2,name:'a'},{id:3,name:'b'}]; const hasTarget = b.some(item => item.id === 2 && item.name === 'a'); console.log(hasTarget); // true
通用场景:封装对象比较函数
如果对象的属性比较多,或者需要重复使用判断逻辑,可以写一个通用的相等判断函数:
function objectsAreEqual(objA, objB) { // 先比较属性数量是否一致 const keysA = Object.keys(objA); const keysB = Object.keys(objB); if (keysA.length !== keysB.length) return false; // 逐个比较属性值 return keysA.every(key => objA[key] === objB[key]); } const b = [{id:2,name:'a'},{id:3,name:'b'}]; const hasTarget = b.some(item => objectsAreEqual(item, {id:2,name:'a'})); console.log(hasTarget); // true
注意:这个简单的比较函数只适用于属性值都是基本类型(字符串、数字、布尔等)的对象,如果对象里还有嵌套对象,你需要递归比较哦~
内容的提问来源于stack exchange,提问作者SCO
相关产品推荐
相关产品推荐

