严格相等运算符将告诉您两个对象类型是否相等。然而,是否有一种方法来判断两个对象是否相等,就像Java中的哈希码值一样?

堆栈溢出问题JavaScript中有hashCode函数吗?类似于这个问题,但需要一个更学术的答案。上面的场景说明了为什么有必要有一个,我想知道是否有等效的解决方案。


当前回答

纯JS方法:我的答案是基于生成一个返回相同值的字符串,无论属性顺序是否相同。设置对象可用于切换大小写和空白是否重要。(为了避免失去焦点,我没有包括那些支持函数,或者我猜应该在任何实用程序集中的isObject。)

这里也没有显示,但为了减少字符串比较时间,如果对象很大,你想加快比较,你也可以散列字符串和比较子字符串;这只适用于非常大的对象(当然也有很小的机会出现错误的相等)。

然后你可以比较genObjStr(obj1) ?= genObjStr(obj2)

function genObjStr(obj, settings) {
// Generate a string that corresponds to an object guarenteed to be the same str even if
// the object have different ordering. The string would largely be used for comparison purposes

var settings = settings||{};
var doStripWhiteSpace = defTrue(settings.doStripWhiteSpace);
var doSetLowerCase = settings.doSetLowerCase||false;

if(isArray(obj)) {
    var vals = [];
    for(var i = 0; i < obj.length; ++i) {
        vals.push(genObjStr(obj[i], settings));
    }
    vals = arraySort(vals);
    return vals.join(`,`);

} else if(isObject(obj)) {

    var keys = Object.keys(obj);
    keys = arraySort(keys);

    var vals = [];
    for(var key of keys) {
        
        var value = obj[key];
        
        value = genObjStr(value, settings);

        if(doStripWhiteSpace) {
            key = removeWhitespace(key);
            var value = removeWhitespace(value);
        };
        if(doSetLowerCase) {
            key = key.toLowerCase();
            value = value.toLowerCase();
        }

        vals.push(value);
    }
    var str = JSON.stringify({keys: keys, vals: vals});
    return str
} else {
    if(doStripWhiteSpace) {
        obj = removeWhitespace(obj);
    };
    if(doSetLowerCase) {
        obj = obj.toLowerCase();
    }
    return obj
}

}

var obj1 = {foo: 123, bar: `Test`};
var obj2 = {bar: `Test`, foo: 123};

console.log(genObjStr(obj1) == genObjStr(obj1))

其他回答

经过这么多的搜索,我找到了以下工作解决方案

function isEquivalent(a, b) {
   // Create arrays of property names
   var aProps = Object.getOwnPropertyNames(a);
   var bProps = Object.getOwnPropertyNames(b);

  // If number of properties is different, objects are not equivalent
  if (aProps.length != bProps.length) {
     return false;
  }

  for (var i = 0; i < aProps.length; i++) {
     var propName = aProps[i];

    // If values of same property are not equal, objects are not equivalent
     if (a[propName] !== b[propName]) {
         return false;
     }
  }

// If we made it this far, objects are considered equivalent
return true; }

更多信息:JavaScript中的对象平等

这里有一个非常基本的方法来检查对象的“值是否相等”。

var john = {
    occupation: "Web Developer",
    age: 25
};

var bobby = {
    occupation: "Web Developer",
    age: 25
};

function isEquivalent(a, b) {
    // Create arrays of property names

    var aProps = Object.getOwnPropertyNames(a);
    var bProps = Object.getOwnPropertyNames(b);

    // If number of properties is different, objects are not equivalent

    if (aProps.length != bProps.length) {
        return false;
    }

    for (var i = 0; i < aProps.length; i++) {
        var propName = aProps[i];

        // If values of same property are not equal, objects are not equivalent
        if (a[propName] !== b[propName]) {
           return false;
        }
    }

    // If we made it this far, objects are considered equivalent
    return true;
}

// Outputs: true
console.log(isEquivalent(john, bobby));

演示 - JSFiddle

如你所见,为了检查对象的“值是否相等”,我们本质上必须遍历对象中的每个属性,以查看它们是否相等。虽然这个简单的实现适用于我们的示例,但有很多情况它无法处理。例如:

如果其中一个属性值本身就是一个对象呢? 如果属性值之一是NaN(中唯一的值 JavaScript不等于它自己?) 如果a有一个值为undefined的属性,而b没有呢 这个属性(因此计算为undefined?)

对于一个健壮的检查对象“值是否相等”的方法,最好依赖于一个经过良好测试的库,它涵盖了各种边缘情况,如下划线。

var john = {
    occupation: "Web Developer",
    age: 25
};

var bobby = {
    occupation: "Web Developer",
    age: 25
};

// Outputs: true
console.log(_.isEqual(john, bobby));

演示 - JSFiddle

如果你在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 " > < /脚本>

我不知道是否有人发布过类似的东西,但这是我做的一个检查对象相等的函数。

function objectsAreEqual(a, b) {
  for (var prop in a) {
    if (a.hasOwnProperty(prop)) {
      if (b.hasOwnProperty(prop)) {
        if (typeof a[prop] === 'object') {
          if (!objectsAreEqual(a[prop], b[prop])) return false;
        } else {
          if (a[prop] !== b[prop]) return false;
        }
      } else {
        return false;
      }
    }
  }
  return true;
}

而且,它是递归的,所以它也可以检查深度相等,如果你这么称呼它的话。

我写了一个运行在Node.js和浏览器上的小库,叫做compare.js。它提供了常见的比较运算符,例如==,!=,>,>=,<,<=和所有JavaScript数据类型的标识符。

例如,你可以用

cmp.eq(obj1, obj2);

这将检查是否相等(使用深度相等的方法)。否则,如果你这样做

cmp.id(obj1, obj2);

它将通过引用进行比较,从而检查标识。 您还可以在对象上使用<和>,它们表示子集和超集。

Compare.js被近700个单元测试覆盖,因此它应该不会有太多的bug;-)。

你可以在https://github.com/goloroden/compare.js上免费找到它,它是MIT许可下的开源软件。