在javascript中不能直接用==或===比较数组,因为它们比较的是引用地址而非内容,即使两个数组元素相同,只要不是同一对象实例,结果就为false;要准确判断数组内容是否一致,需进行逐元素比较,对于只含原始类型的数组可使用浅层比较函数如shallowarrayequal,通过检查长度和every方法实现;而处理包含对象或嵌套数组的复杂结构时,必须采用深层比较策略,推荐使用递归的deepequal函数,它能依次比较类型、长度、键值并递归处理嵌套结构,确保内容完全一致,相比之下json.stringify方法虽简便但因键序敏感、忽略函数和undefined等问题而不适用于严谨场景。

在JavaScript里比较两个数组是否相同,可不是简单地用
==
===
false
要实现一个比较健壮的数组比较函数,特别是当数组中可能包含对象或嵌套数组时,我们需要一个递归的深层比较方法。
// 辅助的深比较函数,用于处理对象和数组。
// 在实际应用中,这通常是一个更复杂的通用函数,能够处理更多边缘情况。
function deepEqual(a, b) {
// 1. 原始类型和引用相同的情况
if (a === b) return true;
// 2. 其中一个不是对象或为null,但它们不相等(已经排除了a===b的情况)
if (a == null || typeof a != "object" ||
b == null || typeof b != "object") {
return false;
}
// 3. 处理数组类型
if (Array.isArray(a) && Array.isArray(b)) {
// 长度不同直接返回false
if (a.length !== b.length) return false;
// 递归比较数组的每个元素
for (let i = 0; i < a.length; i++) {
if (!deepEqual(a[i], b[i])) {
return false;
}
}
return true;
}
// 4. 处理普通对象类型 (非数组对象)
if (a.constructor !== b.constructor) return false; // 确保构造函数相同,例如都是普通对象
const keysA = Object.keys(a);
const keysB = Object.keys(b);
// 键的数量不同直接返回false
if (keysA.length !== keysB.length) return false;
// 递归比较对象的每个属性值
for (let i = 0; i < keysA.length; i++) {
const key = keysA[i];
// 检查b是否包含a的当前key,并且对应的value是否深层相等
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) {
return false;
}
}
return true;
}
// 示例用法:
// console.log(deepEqual([1, 2, [3, 4]], [1, 2, [3, 4]])); // true
// console.log(deepEqual([1, 2, {a: 1}], [1, 2, {a: 1}])); // true
// console.log(deepEqual([1, 2, {a: 1}], [1, 2, {a: 2}])); // false
// console.log(deepEqual([1, 2, [3, 4]], [1, 2, [3, 5]])); // false
// console.log(deepEqual([1, 2, 3], [1, 2, 3])); // true
// console.log(deepEqual([1, 2, 3], [1, 2, 4])); // false
// console.log(deepEqual([1, 2, 3], [1, 2])); // false
// console.log(deepEqual({a: 1, b: [2, 3]}, {a: 1, b: [2, 3]})); // true
// console.log(deepEqual({a: 1, b: [2, 3]}, {b: [2, 3], a: 1})); // true (处理对象键序)这个
deepEqual
==
===
这其实是JavaScript里一个很基础,但也常常让人困惑的点。简单来说,
==
===
所以,当你写
[1, 2, 3] === [1, 2, 3]
false
==
===
如果你的数组里只包含原始类型(数字、字符串、布尔值、
null
undefined
Symbol
BigInt
比如说,我们可以这样:
function shallowArrayEqual(arr1, arr2) {
// 快速检查,如果不是数组或者长度不同,直接返回false
if (!Array.isArray(arr1) || !Array.isArray(arr2) || arr1.length !== arr2.length) {
return false;
}
// 使用every方法,如果所有元素都相等,则返回true
// 这里只适用于比较原始类型或引用相同的对象
return arr1.every((value, index) => value === arr2[index]);
}
// 示例:
// console.log(shallowArrayEqual([1, 'a', true], [1, 'a', true])); // true
// console.log(shallowArrayEqual([1, 'a', true], [1, 'b', true])); // false
// console.log(shallowArrayEqual([1, {a:1}], [1, {a:1}])); // false,因为对象引用不同Array.prototype.every()
false
every()
false
true
every()
true
当数组中包含了其他对象(包括嵌套数组)时,事情就变得复杂起来了,因为简单的
===
几种常见的策略:
自定义递归函数 (推荐): 就像前面“解决方案”中提供的
deepEqual
===
null
undefined
Symbol
JSON.stringify()
function compareArraysByJSON(arr1, arr2) {
try {
return JSON.stringify(arr1) === JSON.stringify(arr2);
} catch (e) {
// 处理循环引用等JSON.stringify无法处理的情况
return false;
}
}
// 示例:
// console.log(compareArraysByJSON([1, {a: 1}], [1, {a: 1}])); // true
// console.log(compareArraysByJSON([1, {b: 1, a: 1}], [1, {a: 1, b: 1}])); // false!注意对象的键序问题
// console.log(compareArraysByJSON([1, undefined], [1, undefined])); // true
// console.log(compareArraysByJSON([1, function(){}], [1, function(){}])); // false,函数会被忽略这种方法非常不推荐用于生产环境的严谨比较,因为它有几个明显的局限性:
以上就是js 怎样比较两个数组是否相同的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号