在JavaScript中比较对象的最佳方法是什么?
例:
var user1 = {name : "nerd", org: "dev"};
var user2 = {name : "nerd", org: "dev"};
var eq = user1 == user2;
alert(eq); // gives false
我知道如果 两个对象引用的是完全相同的对象 , 则它们相等 ,但是有没有办法检查它们是否具有相同的属性值?
以下方法对我有用,但这是唯一的可能性吗?
var eq = Object.toJSON(user1) == Object.toJSON(user2);
alert(eq); // gives true
不幸的是,除非您_proto_
递归使用并访问所有不可枚举的属性,否则没有完美的方法,但这仅在Firefox中有效。
因此,我能做的最好是猜测使用情况。
当您具有简单的JSON样式的对象,而内部没有方法和DOM节点时,则可以使用:
JSON.stringify(obj1) === JSON.stringify(obj2)
属性的ORDER重要,因此对于以下对象,此方法将返回false:
x = {a: 1, b: 2};
y = {b: 2, a: 1};
在不深入研究原型的情况下比较对象,然后递归比较属性的投影,还比较构造函数。
这几乎是正确的算法:
function deepCompare () {
var i, l, leftChain, rightChain;
function compare2Objects (x, y) {
var p;
// remember that NaN === NaN returns false
// and isNaN(undefined) returns true
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
return true;
}
// Compare primitives and functions.
// Check if both arguments link to the same object.
// Especially useful on the step where we compare prototypes
if (x === y) {
return true;
}
// Works in case when functions are created in constructor.
// Comparing dates is a common scenario. Another built-ins?
// We can even handle functions passed across iframes
if ((typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)) {
return x.toString() === y.toString();
}
// At last checking prototypes as good as we can
if (!(x instanceof Object && y instanceof Object)) {
return false;
}
if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
return false;
}
if (x.constructor !== y.constructor) {
return false;
}
if (x.prototype !== y.prototype) {
return false;
}
// Check for infinitive linking loops
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
return false;
}
// Quick checking of one object being a subset of another.
// todo: cache the structure of arguments[0] for performance
for (p in y) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
}
else if (typeof y[p] !== typeof x[p]) {
return false;
}
}
for (p in x) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
}
else if (typeof y[p] !== typeof x[p]) {
return false;
}
switch (typeof (x[p])) {
case 'object':
case 'function':
leftChain.push(x);
rightChain.push(y);
if (!compare2Objects (x[p], y[p])) {
return false;
}
leftChain.pop();
rightChain.pop();
break;
default:
if (x[p] !== y[p]) {
return false;
}
break;
}
}
return true;
}
if (arguments.length < 1) {
return true; //Die silently? Don't know how to handle such case, please help...
// throw "Need two or more arguments to compare";
}
for (i = 1, l = arguments.length; i < l; i++) {
leftChain = []; //Todo: this can be cached
rightChain = [];
if (!compare2Objects(arguments[0], arguments[i])) {
return false;
}
}
return true;
}
已知问题(嗯,它们的优先级很低,可能您永远不会注意到它们):
问题内容: 我想比较JavaScript代码中2个对象数组。这些对象共有8个属性,但是每个对象都不会有一个值,并且每个数组的大小永远都不能超过8个,因此可能要使用遍历每个对象然后查看对象的值的蛮力方法。 8个属性是执行我想做的最简单的方法,但是在实现之前,我想看看是否有人有一个更优雅的解决方案。有什么想法吗? 问题答案: 编辑:您不能在JavaScript解释器的当前基于浏览器的常见实现中重载运算
问题内容: 当比较Javascript中的日期对象时,我发现即使比较同一日期也不会返回true。 我如何比较这些日期的相等性?我对利用JS 的本机对象(而不是任何第三方库)感兴趣,因为它不适合仅使用第三方JS来比较日期。 问题答案: 这是因为在第二种情况下,将比较实际的日期对象,并且两个对象永远不会彼此相等。强迫他们编号: 如果要更明确地转换为数字,请使用以下任一方法: 要么 哦,对规范的引用:§
问题内容: 是否可以比较2组json对象的差异?我所拥有的是一个通过jquery $ post()轮询JSON对象的脚本。我想要做的是拿走刚刚被轮询的对象,并将其与存储的对象进行比较。如果一个与另一个之间有任何更改,请将其应用于存储对象或替换(以任何一种方式替换),但是从UI角度来看,我正在通过查找两者之间的差异,将更改无缝地应用于JSON对象。 2.之所以要这样做,是因为现在我已经拥有了UI,因
问题内容: 我希望能够使LinkedList.contains()对于自定义比较器返回true。 假设我有1个LinkedList和2个对象 从技术上讲,两个对象在比较方面是相同的(MyObject实现Comparable) (a == b)==真 但是,当我执行以下操作时,myList对于myList.contains(b)不会返回true 我认为它是因为contains将检查对象引用,并看到a
问题内容: 可以对Angular中的两个对象进行“深度”比较吗?我想做的是比较每个键/值对。例如: 对象1 对象2 我需要的是比较失败,因为只有一对键/值对是不同的。换句话说,所有键/值对必须完全匹配,否则将失败。这是Angular中已经内置的东西吗?我确信如果确实需要,我可以编写自己的服务,但我希望它已经内置。类似于angular.equals。 问题答案: 要比较两个对象,可以使用: 它进行了
我有2个对象数组和2个如果条件 编辑网格行时,和将具有相同的长度,因此第一个if条件执行。当我添加新行时,长度将超过,因此第二个如果条件执行。 但我有一种情况,用户可以添加一个新行,然后立即编辑一个现有行。在那个特定的场景中,我需要执行if条件,并且我停留在那里。我们将听取任何建议。谢谢