严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
当前回答
这取决于你对平等的定义。因此,作为类的开发人员,要由您来定义它们的相等性。
有时会使用一种情况,如果两个实例指向内存中的相同位置,则认为它们是“相等的”,但这并不总是您想要的。例如,如果我有一个Person类,如果两个Person对象具有相同的Last Name、First Name和Social Security Number(即使它们指向内存中的不同位置),我可能会认为它们是“相等的”。
另一方面,我们不能简单地说两个对象是相等的,如果它们的每个成员的值都相同,因为,有时,你并不想这样。换句话说,对于每个类,由类开发人员定义组成对象“标识”的成员并开发适当的相等操作符(通过重载==操作符或Equals方法)。
Saying that two objects are equal if they have the same hash is one way out. However you then have to wonder how the hash is calculated for each instance. Going back to the Person example above, we could use this system if the hash was calculated by looking at the values of the First Name, Last Name, and Social Security Number fields. On top of that, we are then relying on the quality of the hashing method (that's a huge topic on its own, but suffice it to say that not all hashes are created equal, and bad hashing methods can lead to more collisions, which in this case would return false matches).
其他回答
下面的一些解决方案在性能、功能和风格方面存在问题……它们没有经过充分的考虑,其中一些在不同的情况下失败了。我试图在自己的解决方案中解决这个问题,我非常感谢您的反馈:
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;
};
最简单和逻辑的解决方案,比较一切像对象,数组,字符串,Int…
JSON。stringify({a: val1}) == JSON。stringify ({a: val2})
注意:
你需要用你的Object替换val1和val2 对于对象,必须对两侧对象进行递归排序(按键)
如果你在AngularJS中工作,angular。Equals函数将确定两个对象是否相等。在Ember.js中使用isEqual。
角。equals -关于这个方法的更多信息,请参阅文档或源代码。它还对数组进行了深度比较。 js isEqual -关于这个方法的更多信息,请参阅文档或源代码。它不会对数组进行深度比较。
Var紫色=[{"紫色":"喝了"}]; Var drinking =[{"紫色":"喝了"}]; 如果(角。等于(紫色,喝)){ 文档。写(有dat); } < script src = " https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js " > < /脚本>
虽然这个问题已经有很多答案了。我只是想提供另一种实现方法:
const primitveDataTypes = ['number', 'boolean', 'string', 'undefined']; const isDateOrRegExp = (value) => value instanceof Date || value instanceof RegExp; const compare = (first, second) => { let agg = true; if(typeof first === typeof second && primitveDataTypes.indexOf(typeof first) !== -1 && first !== second){ agg = false; } // adding support for Date and RegExp. else if(isDateOrRegExp(first) || isDateOrRegExp(second)){ if(first.toString() !== second.toString()){ agg = false; } } else { if(Array.isArray(first) && Array.isArray(second)){ if(first.length === second.length){ for(let i = 0; i < first.length; i++){ if(typeof first[i] === 'object' && typeof second[i] === 'object'){ agg = compare(first[i], second[i]); } else if(first[i] !== second[i]){ agg = false; } } } else { agg = false; } } else { const firstKeys = Object.keys(first); const secondKeys = Object.keys(second); if(firstKeys.length !== secondKeys.length){ agg = false; } for(let j = 0 ; j < firstKeys.length; j++){ if(firstKeys[j] !== secondKeys[j]){ agg = false; } if(first[firstKeys[j]] && second[secondKeys[j]] && typeof first[firstKeys[j]] === 'object' && typeof second[secondKeys[j]] === 'object'){ agg = compare(first[firstKeys[j]], second[secondKeys[j]]); } else if(first[firstKeys[j]] !== second[secondKeys[j]]){ agg = false; } } } } return agg; } console.log('result', compare({a: 1, b: { c: [4, {d:5}, {e:6}]}, r: null}, {a: 1, b: { c: [4, {d:5}, {e:6}]}, r: 'ffd'})); //returns false.
我已经实现了一个方法,它接受两个json,并使用递归检查它们的键是否具有相同的值。 我用另一个问题来解决这个问题。
const arraysEqual = (a, b) => { if (a === b) return true; if (a === null || b === null) return false; if (a.length !== b.length) return false; // If you don't care about the order of the elements inside // the array, you should sort both arrays here. for (let i = 0; i < a.length; ++i) { if (a[i] !== b[i]) return false; } return true; }; const jsonsEqual = (a, b) => { if(typeof a !== 'object' || typeof b !== 'object') return false; if (Object.keys(a).length === Object.keys(b).length) { // if items have the same size let response = true; for (let key in a) { if (!b[key]) // if not key response = false; if (typeof a[key] !== typeof b[key]) // if typeof doesn't equals response = false; else { if (Array.isArray(a[key])) // if array response = arraysEqual(a[key], b[key]); else if (typeof a[key] === 'object') // if another json response = jsonsEqual(a[key], b[key]); else if (a[key] !== b[key]) // not equals response = false; } if (!response) // return if one item isn't equal return false; } } else return false; return true; }; const json1 = { a: 'a', b: 'asd', c: [ '1', 2, 2.5, '3', { d: 'asd', e: [ 1.6, { f: 'asdasd', g: '123' } ] } ], h: 1, i: 1.2, }; const json2 = { a: 'nops', b: 'asd' }; const json3 = { a: 'h', b: '484', c: [ 3, 4.5, '2ss', { e: [ { f: 'asdasd', g: '123' } ] } ], h: 1, i: 1.2, }; const result = jsonsEqual(json1,json2); //const result = jsonsEqual(json1,json3); //const result = jsonsEqual(json1,json1); if(result) // is equal $('#result').text("Jsons are the same") else $('#result').text("Jsons aren't equals") <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="result"></div>