严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?
堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。
当前回答
你可以使用_。isEqual(obj1, obj2)来自underscore.js库。
这里有一个例子:
var stooge = {name: 'moe', luckyNumbers: [13, 27, 34]};
var clone = {name: 'moe', luckyNumbers: [13, 27, 34]};
stooge == clone;
=> false
_.isEqual(stooge, clone);
=> true
在这里查看官方文档:http://underscorejs.org/#isEqual
其他回答
需要一个比已经发布的更通用的对象比较函数,我炮制了以下。批判赞赏……
Object.prototype.equals = function(iObj) {
if (this.constructor !== iObj.constructor)
return false;
var aMemberCount = 0;
for (var a in this) {
if (!this.hasOwnProperty(a))
continue;
if (typeof this[a] === 'object' && typeof iObj[a] === 'object' ? !this[a].equals(iObj[a]) : this[a] !== iObj[a])
return false;
++aMemberCount;
}
for (var a in iObj)
if (iObj.hasOwnProperty(a))
--aMemberCount;
return aMemberCount ? false : true;
}
当然,当我们在它的时候,我会抛出我自己对车轮的重新发明(我为辐条和使用的材料的数量感到自豪):
////////////////////////////////////////////////////////////////////////////////
var equals = function ( objectA, objectB ) {
var result = false,
keysA,
keysB;
// Check if they are pointing at the same variable. If they are, no need to test further.
if ( objectA === objectB ) {
return true;
}
// Check if they are the same type. If they are not, no need to test further.
if ( typeof objectA !== typeof objectB ) {
return false;
}
// Check what kind of variables they are to see what sort of comparison we should make.
if ( typeof objectA === "object" ) {
// Check if they have the same constructor, so that we are comparing apples with apples.
if ( objectA.constructor === objectA.constructor ) {
// If we are working with Arrays...
if ( objectA instanceof Array ) {
// Check the arrays are the same length. If not, they cannot be the same.
if ( objectA.length === objectB.length ) {
// Compare each element. They must be identical. If not, the comparison stops immediately and returns false.
return objectA.every(
function ( element, i ) {
return equals( element, objectB[ i ] );
}
);
}
// They are not the same length, and so are not identical.
else {
return false;
}
}
// If we are working with RegExps...
else if ( objectA instanceof RegExp ) {
// Return the results of a string comparison of the expression.
return ( objectA.toString() === objectB.toString() );
}
// Else we are working with other types of objects...
else {
// Get the keys as arrays from both objects. This uses Object.keys, so no old browsers here.
keysA = Object.keys( objectA );
keysB = Object.keys( objectB );
// Check the key arrays are the same length. If not, they cannot be the same.
if ( keysA.length === keysB.length ) {
// Compare each property. They must be identical. If not, the comparison stops immediately and returns false.
return keysA.every(
function ( element ) {
return equals( objectA[ element ], objectB[ element ] );
}
);
}
// They do not have the same number of keys, and so are not identical.
else {
return false;
}
}
}
// They don't have the same constructor.
else {
return false;
}
}
// If they are both functions, let us do a string comparison.
else if ( typeof objectA === "function" ) {
return ( objectA.toString() === objectB.toString() );
}
// If a simple variable type, compare directly without coercion.
else {
return ( objectA === objectB );
}
// Return a default if nothing has already been returned.
return result;
};
////////////////////////////////////////////////////////////////////////////////
它会尽可能快地返回false,但当然,对于一个差异嵌套很深的大对象,它可能不那么有效。在我自己的场景中,良好地处理嵌套数组非常重要。
希望它能帮助需要这种“轮子”的人。
我不是Javascript专家,但这里有一个简单的解决方法。我检查三件事:
它是一个对象,而且它不是null,因为typeof null是对象。 如果两个对象的属性计数相同?否则它们就不相等。 遍历一个对象的属性,并检查对应的属性在第二个对象中是否具有相同的值。
function deepEqual (first, second) { // Not equal if either is not an object or is null. if (!isObject(first) || !isObject(second) ) return false; // If properties count is different if (keys(first).length != keys(second).length) return false; // Return false if any property value is different. for(prop in first){ if (first[prop] != second[prop]) return false; } return true; } // Checks if argument is an object and is not null function isObject(obj) { return (typeof obj === "object" && obj != null); } // returns arrays of object keys function keys (obj) { result = []; for(var key in obj){ result.push(key); } return result; } // Some test code obj1 = { name: 'Singh', age: 20 } obj2 = { age: 20, name: 'Singh' } obj3 = { name: 'Kaur', age: 19 } console.log(deepEqual(obj1, obj2)); console.log(deepEqual(obj1, obj3));
如何确定部分对象(partial <T>)等于typescript中的原始对象(T)。
function compareTwoObjects<T>(original: T, partial: Partial<T>): boolean {
return !Object.keys(partial).some((key) => partial[key] !== original[key]);
}
附注:最初我打算提出一个有答案的新问题。但这样的问题已经存在,并被标记为重复题。
我写这个方法只是为了确保数组和对象都能被清晰地比较。
这应该也能做到!:)
public class Objects {
/**
* Checks whether a value is of type Object
* @param value the value
*/
public static isObject = (value: any): boolean => {
return value === Object(value) && Object.prototype.toString.call(value) !== '[object Array]'
}
/**
* Checks whether a value is of type Array
* @param value the value
*/
public static isArray = (value: any): boolean => {
return Object.prototype.toString.call(value) === '[object Array]' && !Objects.isObject(value)
}
/**
* Check whether two values are equal
*/
public static isEqual = (objectA: any, objectB: any) => {
// Objects
if (Objects.isObject(objectA) && !Objects.isObject(objectB)) {
return false
}
else if (!Objects.isObject(objectA) && Objects.isObject(objectB)) {
return false
}
// Arrays
else if (Objects.isArray(objectA) && !Objects.isArray(objectB)) {
return false
}
else if (!Objects.isArray(objectA) && Objects.isArray(objectB)) {
return false
}
// Primitives
else if (!Objects.isArray(objectA) && !Objects.isObject(objectA)) {
return objectA === objectB
}
// Object or array
else {
const compareObject = (objectA: any, objectB: any): boolean => {
if (Object.keys(objectA).length !== Object.keys(objectB).length) return false
for (const propertyName of Object.keys(objectA)) {
const valueA = objectA[propertyName]
const valueB = objectB[propertyName]
if (!Objects.isEqual(valueA, valueB)) {
return false
}
}
return true
}
const compareArray = (arrayA: any[], arrayB: any[]): boolean => {
if (arrayA.length !== arrayB.length) return false
for (const index in arrayA) {
const valueA = arrayA[index]
const valueB = arrayB[index]
if (!Objects.isEqual(valueA, valueB)) {
return false
}
}
return true
}
if (Objects.isObject(objectA)) {
return compareObject(objectA, objectB)
} else {
return compareArray(objectA, objectB)
}
}
}
}