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

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


当前回答

是的,另一个答案……

Object.prototype.equals = function (object) { if (this.constructor !== object.constructor) return false; if (Object.keys(this).length !== Object.keys(object).length) return false; var obk; for (obk in object) { if (this[obk] !== object[obk]) return false; } return true; } var aaa = JSON.parse('{"name":"mike","tel":"1324356584"}'); var bbb = JSON.parse('{"tel":"1324356584","name":"mike"}'); var ccc = JSON.parse('{"name":"mike","tel":"584"}'); var ddd = JSON.parse('{"name":"mike","tel":"1324356584", "work":"nope"}'); $("#ab").text(aaa.equals(bbb)); $("#ba").text(bbb.equals(aaa)); $("#bc").text(bbb.equals(ccc)); $("#ad").text(aaa.equals(ddd)); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> aaa equals bbb? <span id="ab"></span> <br/> bbb equals aaa? <span id="ba"></span> <br/> bbb equals ccc? <span id="bc"></span> <br/> aaa equals ddd? <span id="ad"></span>

其他回答

我看到了意大利式的代码答案。 不使用任何第三方的lib,这是非常容易的。

首先,按键对两个对象进行排序。

let objectOne = { hey, you }
let objectTwo = { you, hey }

// If you really wanted you could make this recursive for deep sort.
const sortObjectByKeyname = (objectToSort) => {
    return Object.keys(objectToSort).sort().reduce((r, k) => (r[k] = objectToSort[k], r), {});
}

let objectOne = sortObjectByKeyname(objectOne)
let objectTwo = sortObjectByKeyname(objectTwo)

然后简单地使用字符串来比较它们。

JSON.stringify(objectOne) === JSON.stringify(objectTwo)

这是一个非常干净的CoffeeScript版本,你可以这样做:

Object::equals = (other) ->
  typeOf = Object::toString

  return false if typeOf.call(this) isnt typeOf.call(other)
  return `this == other` unless typeOf.call(other) is '[object Object]' or
                                typeOf.call(other) is '[object Array]'

  (return false unless this[key].equals other[key]) for key, value of this
  (return false if typeof this[key] is 'undefined') for key of other

  true

下面是测试:

  describe "equals", ->

    it "should consider two numbers to be equal", ->
      assert 5.equals(5)

    it "should consider two empty objects to be equal", ->
      assert {}.equals({})

    it "should consider two objects with one key to be equal", ->
      assert {a: "banana"}.equals {a: "banana"}

    it "should consider two objects with keys in different orders to be equal", ->
      assert {a: "banana", kendall: "garrus"}.equals {kendall: "garrus", a: "banana"}

    it "should consider two objects with nested objects to be equal", ->
      assert {a: {fruit: "banana"}}.equals {a: {fruit: "banana"}}

    it "should consider two objects with nested objects that are jumbled to be equal", ->
      assert {a: {a: "banana", kendall: "garrus"}}.equals {a: {kendall: "garrus", a: "banana"}}

    it "should consider two objects with arrays as values to be equal", ->
      assert {a: ["apple", "banana"]}.equals {a: ["apple", "banana"]}



    it "should not consider an object to be equal to null", ->
      assert !({a: "banana"}.equals null)

    it "should not consider two objects with different keys to be equal", ->
      assert !({a: "banana"}.equals {})

    it "should not consider two objects with different values to be equal", ->
      assert !({a: "banana"}.equals {a: "grapefruit"})

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

我需要模拟jQuery POST请求,因此对我来说重要的是两个对象具有相同的属性集(任何一个对象中都不缺少属性),并且每个属性值都是“相等的”(根据这个定义)。我不关心对象是否有不匹配的方法。

这是我将使用的,它应该足以满足我的特定要求:

function PostRequest() {
    for (var i = 0; i < arguments.length; i += 2) {
        this[arguments[i]] = arguments[i+1];
    }

    var compare = function(u, v) {
        if (typeof(u) != typeof(v)) {
            return false;
        }

        var allkeys = {};
        for (var i in u) {
            allkeys[i] = 1;
        }
        for (var i in v) {
            allkeys[i] = 1;
        }
        for (var i in allkeys) {
            if (u.hasOwnProperty(i) != v.hasOwnProperty(i)) {
                if ((u.hasOwnProperty(i) && typeof(u[i]) == 'function') ||
                    (v.hasOwnProperty(i) && typeof(v[i]) == 'function')) {
                    continue;
                } else {
                    return false;
                }
            }
            if (typeof(u[i]) != typeof(v[i])) {
                return false;
            }
            if (typeof(u[i]) == 'object') {
                if (!compare(u[i], v[i])) {
                    return false;
                }
            } else {
                if (u[i] !== v[i]) {
                    return false;
                }
            }
        }

        return true;
    };

    this.equals = function(o) {
        return compare(this, o);
    };

    return this;
}

像这样使用:

foo = new PostRequest('text', 'hello', 'html', '<p>hello</p>');
foo.equals({ html: '<p>hello</p>', text: 'hello' });

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

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;
}

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