数组是 JavaScript 中的对象,所以 三等号运算符 ===
只返回 true
如果数组是相同的引用。
const a = [1, 2, 3];
const b = [1, 2, 3];
a === a; // true
a === b; // false
如何比较两个数组是否相等? 相等是一个棘手的主题:JavaScript 规范定义了 4 种不同的方法来检查两个值是否 相等,并且没有考虑对象之间的深度相等。
在这种情况下,尽可能明确地说明 平等 的含义是有帮助的。 在软件工程中,以正确的方式提出问题通常会使答案显而易见。
考虑到这一点,这里有 3 个数组相等的定义以及如何检查它们。
长度相同,每个值相等
一种比较方法 a
和 b
正在检查是否每个值 a
严格等于对应的值 b
, 如果数组的所有元素都是基元而不是对象,则此方法效果很好。
const a = [1, 2, 3];
const b = [4, 5, 6];
const c = [1, 2, 3];
function arrayEquals(a, b) {
return Array.isArray(a) &&
Array.isArray(b) &&
a.length === b.length &&
a.every((val, index) => val === b[index]);
}
arrayEquals(a, b); // false
arrayEquals(a, c); // true
深度平等 POJO
以前的 arrayEquals()
函数适用于原始值,但如果您想按值比较对象,则效果不佳。
const a = [{ answer: 42 }, { powerLevel: 9001 }];
const b = [{ answer: 42 }, { powerLevel: 9001 }];
// false, because { answer: 42 } !== { answer: 42 }, different references
arrayEquals(a, b);
考虑对象值的一种巧妙方法是比较数组 JSON.stringify()
输出。
const a = [{ answer: 42 }, { powerLevel: 9001 }];
const b = [{ answer: 42 }, { powerLevel: 9001 }];
const c = [{ answer: 42 }, { password: taco }];
JSON.stringify(a) === JSON.stringify(b); // true
JSON.stringify(a) === JSON.stringify(c); // false
这种方法很方便,因为它需要最少的代码并且不需要外部库。 然而比较 JSON.stringify()
输出有一个不幸的边缘情况,根据您的用例,这可能是一个问题。 自从 undefined
不是有效的 JSON 值,以下数组具有相同的 JSON.stringify()
输出,因为 JSON.stringify()
转换 undefined
至 null
。
const a = [undefined];
const b = [null];
使用 Lodash 的 isEqual()
除了 null
对比 undefined
怪癖,比较 JSON.stringify()
输出也不考虑对象类型。 JSON.stringify()
是有关,一个对象与 toJSON()
返回 42 的函数与数字 42 相同。
const a = [{ toJSON: () => 42 }];
const b = [42];
JSON.stringify(a); // [42]
JSON.stringify(b); // [42]
同样,自定义对象与 POJO 相同:
class MyClass {
constructor(obj) {
Object.assign(this, obj);
}
}
const a = [new MyClass({ answer: 42 })];
const b = [{ answer: 42 }];
JSON.stringify(a) === JSON.stringify(b); // true
Lodash 的 isEqual()
function 另一方面:
const _ = require(lodash);
class MyClass {
constructor(obj) {
Object.assign(this, obj);
}
}
const a = [new MyClass({ answer: 42 })];
const b = [{ answer: 42 }];
_.isEqual(a, b); // false
Lodash 的 isEqual()
如果您需要检查对象是否具有相同的类的所有花里胡哨的功能,那么函数就是您要走的路。JSON.stringify()
方法适用于 POJO,只要确保您考虑到 null
并且仅将其与受信任的数据一起使用 – toJSON()
可能是一个安全漏洞。
请登录后查看评论内容