
本文讲解如何正确判断一个对象数组中是否存在某个对象,其 puzzle 属性(为数组)与目标对象的 puzzle 数组内容完全相等——需逐项比对,而非引用相等。
本文讲解如何正确判断一个对象数组中是否存在某个对象,其 puzzle 属性(为数组)与目标对象的 puzzle 数组**内容完全相等**——需逐项比对,而非引用相等。
在 JavaScript 中,数组是引用类型,直接使用 === 或 == 比较两个数组(即使元素完全相同)总会返回 false,因为它们指向内存中不同的地址。例如:
[1, 2, 3] === [1, 2, 3] // false
因此,当你调用 arr.some(item => item.puzzle === element.puzzle) 时,实际比较的是两个数组的引用,而非内容,自然返回 false——这正是你遇到问题的根本原因。
✅ 正确做法是:深度比较 puzzle 数组的内容。推荐使用 Array.prototype.every() 配合长度校验,确保两数组长度一致且每个索引位置的值严格相等:
const arrHasPuzzle = arr.some(({ puzzle }) =>
puzzle.length === element.puzzle.length &&
puzzle.every((val, index) => val === element.puzzle[index])
);
该逻辑分两步:
- 先校验
length:避免因长度不同导致every()提前短路或误判; - 再用
every()遍历puzzle,逐项比对element.puzzle[i],确保所有元素一一对应且值相等(使用===保证类型和值均一致)。
? 若还需获取匹配的对象(而不仅是布尔结果),可改用 find():
const matched = arr.find(({ puzzle }) =>
puzzle.length === element.puzzle.length &&
puzzle.every((val, i) => val === element.puzzle[i])
);
// matched 将是 { puzzle: [1,3,4,8,0,2,7,6,5], children: [] }
⚠️ 注意事项:
- 此方法假设
puzzle始终为一维数字数组;若含嵌套结构或非原始类型(如对象、NaN),需升级为深比较(如JSON.stringify()简单场景,或使用 Lodash 的isEqual); -
every()在空数组上返回true,因此长度校验必不可少,否则[].every(...)可能产生意外true; - 若性能敏感且数组极大,可考虑提前
break的for循环,但some/find+every在绝大多数场景下已足够清晰高效。
总结:判断数组中对象是否包含“内容相同”的子数组,关键在于放弃引用比较,转向结构化内容比对——长度一致 + 元素全等,是简洁、可靠、符合直觉的标准解法。










