严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
当前回答
使用JSON.stringify()并不总是可靠的。所以在我看来,这种方法是你问题的最佳解决方案
首先,不,没有通用的方法来确定一个对象是否相等!
但是有一个概念叫做浅平等比较。 有一个npm库可以帮助你使用这个概念
例子
const shallowequal = require('shallowequal');
const object = { 'user': 'fred' };
const other = { 'user': 'fred' };
// Referential Equality Comparison (`strict ===`)
object === other; // → false
// Shallow Equality Comparison
shallowequal(object, other); // → true
如果你想知道如何创建shallowEqual比较方法,那么请参考这里。它来自开源的fbjs Facebook库。
浅平等比较
shallowequal(其中obj1 methoda)
shallowEqual在两个值(即obj1和obj2)之间进行浅相等比较,以确定它们是否相等。
相等性是通过迭代给定obj1上的键来执行的,并且当任何键的值在obj1和obj2之间不严格相等时返回false。否则,只要所有键的值严格相等,就返回true。
其他回答
这是一个简单的Javascript函数,用于比较具有简单键值对的两个对象。该函数将返回一个字符串数组,其中每个字符串是到两个对象之间的一个不等式的路径。
function compare(a,b) {
var paths = [];
[...new Set(Object.keys(a).concat(Object.keys(b)))].forEach(key=>{
if(typeof a[key] === 'object' && typeof b[key] === 'object') {
var results = compare(a[key], b[key]);
if(JSON.stringify(results)!=='[]') {
paths.push(...results.map(result=>key.concat("=>"+result)));
}
}
else if (a[key]!==b[key]) {
paths.push(key);
}
})
return paths;
}
如果你只想比较两个对象,而不知道不等式的路径,你可以这样做:
if(JSON.stringify(compare(object1, object2))==='[]') {
// the two objects are equal
} else {
// the two objects are not equal
}
下面的一些解决方案在性能、功能和风格方面存在问题……它们没有经过充分的考虑,其中一些在不同的情况下失败了。我试图在自己的解决方案中解决这个问题,我非常感谢您的反馈:
http://stamat.wordpress.com/javascript-object-comparison/
//Returns the object's class, Array, Date, RegExp, Object are of interest to us
var getClass = function(val) {
return Object.prototype.toString.call(val)
.match(/^\[object\s(.*)\]$/)[1];
};
//Defines the type of the value, extended typeof
var whatis = function(val) {
if (val === undefined)
return 'undefined';
if (val === null)
return 'null';
var type = typeof val;
if (type === 'object')
type = getClass(val).toLowerCase();
if (type === 'number') {
if (val.toString().indexOf('.') > 0)
return 'float';
else
return 'integer';
}
return type;
};
var compareObjects = function(a, b) {
if (a === b)
return true;
for (var i in a) {
if (b.hasOwnProperty(i)) {
if (!equal(a[i],b[i])) return false;
} else {
return false;
}
}
for (var i in b) {
if (!a.hasOwnProperty(i)) {
return false;
}
}
return true;
};
var compareArrays = function(a, b) {
if (a === b)
return true;
if (a.length !== b.length)
return false;
for (var i = 0; i < a.length; i++){
if(!equal(a[i], b[i])) return false;
};
return true;
};
var _equal = {};
_equal.array = compareArrays;
_equal.object = compareObjects;
_equal.date = function(a, b) {
return a.getTime() === b.getTime();
};
_equal.regexp = function(a, b) {
return a.toString() === b.toString();
};
// uncoment to support function as string compare
// _equal.fucntion = _equal.regexp;
/*
* Are two values equal, deep compare for objects and arrays.
* @param a {any}
* @param b {any}
* @return {boolean} Are equal?
*/
var equal = function(a, b) {
if (a !== b) {
var atype = whatis(a), btype = whatis(b);
if (atype === btype)
return _equal.hasOwnProperty(atype) ? _equal[atype](a, b) : a==b;
return false;
}
return true;
};
如果两个对象的所有属性都具有相同的值,并且所有嵌套对象和数组都递归地具有相同的值,那么将它们视为相等是很有用的。我也认为以下两个对象是相等的:
var a = {p1: 1};
var b = {p1: 1, p2: undefined};
类似地,数组可以有“缺失”元素和未定义的元素。我也会同样对待它们:
var c = [1, 2];
var d = [1, 2, undefined];
函数:实现等式定义的函数:
function isEqual(a, b) {
if (a === b) {
return true;
}
if (generalType(a) != generalType(b)) {
return false;
}
if (a == b) {
return true;
}
if (typeof a != 'object') {
return false;
}
// null != {}
if (a instanceof Object != b instanceof Object) {
return false;
}
if (a instanceof Date || b instanceof Date) {
if (a instanceof Date != b instanceof Date ||
a.getTime() != b.getTime()) {
return false;
}
}
var allKeys = [].concat(keys(a), keys(b));
uniqueArray(allKeys);
for (var i = 0; i < allKeys.length; i++) {
var prop = allKeys[i];
if (!isEqual(a[prop], b[prop])) {
return false;
}
}
return true;
}
源代码(包括辅助函数,generalType和uniqueArray): 这里是单元测试和测试运行器。
判断两个对象是否相似的一个快速“破解”方法是使用它们的toString()方法。如果您正在检查对象A和B,请确保A和B具有有意义的toString()方法,并检查它们返回的字符串是否相同。
这不是灵丹妙药,但有时在正确的情况下是有用的。
对象是否相等检查:JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())
上面的测试还适用于对象数组,在这种情况下使用http://www.w3schools.com/jsref/jsref_sort.asp中记录的排序函数
对于具有平面JSON模式的小型数组可能足够了。