995 Stimmen

Wie bestimmt man die Gleichheit zweier JavaScript-Objekte?

Ein strikter Gleichheitsoperator sagt Ihnen, ob zwei Objekte Typen gleich sind. Gibt es jedoch eine Möglichkeit zu erkennen, ob zwei Objekte gleich sind, ähnlich wie der Hash-Code Wert in Java?

Stack Overflow Frage Gibt es irgendeine Art von HashCode-Funktion in JavaScript? ist dieser Frage ähnlich, erfordert aber eine eher akademische Antwort. Das obige Szenario zeigt, warum es notwendig wäre, eine zu haben, und ich frage mich, ob es irgendeine gleichwertige Lösung .

5 Stimmen

Gehen Sie auch dieser Frage nach stackoverflow.com/q/1068834/1671639

55 Stimmen

Beachten Sie, dass auch in Java, a.hashCode() == b.hashCode() tut no bedeuten, dass a ist gleich b . Das ist eine notwendige, aber keine hinreichende Bedingung.

7 Stimmen

Wenn Sie Objekte in Ihrem Code vergleichen MÜSSEN, dann haben Sie Ihren Code wahrscheinlich falsch geschrieben. Die bessere Frage könnte lauten: "Wie kann ich diesen Code so schreiben, dass ich keine Objekte vergleichen muss?"

13voto

Alan R. Soares Punkte 1625

Hier ist eine Lösung in ES6/ES2015 mit einem funktionalen Ansatz:

const typeOf = x => 
  ({}).toString
      .call(x)
      .match(/\[object (\w+)\]/)[1]

function areSimilar(a, b) {
  const everyKey = f => Object.keys(a).every(f)

  switch(typeOf(a)) {
    case 'Array':
      return a.length === b.length &&
        everyKey(k => areSimilar(a.sort()[k], b.sort()[k]));
    case 'Object':
      return Object.keys(a).length === Object.keys(b).length &&
        everyKey(k => areSimilar(a[k], b[k]));
    default:
      return a === b;
  }
}

Demo hier verfügbar

0 Stimmen

Funktioniert nicht, wenn sich die Reihenfolge der Objektschlüssel geändert hat.

12voto

Zac Punkte 789

Ich weiß nicht, ob schon jemand etwas Ähnliches gepostet hat, aber hier ist eine Funktion, die ich gemacht habe, um auf Objektgleichheiten zu prüfen.

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

Außerdem ist es rekursiv, so dass es auch auf tiefe Gleichheit prüfen kann, wenn Sie es so nennen.

0 Stimmen

Kleine Korrektur: bevor man die einzelnen Requisiten in a und b durchgeht, sollte man diese Prüfung hinzufügen if(Object.getOwnPropertyNames(a).length !== Object.getOwnPropertyNames(b).length ) return false

2 Stimmen

Ist es offensichtlich, dass ein geeigneter Gleichheitsprüfer rekursiv sein muss. Ich denke, dass eine dieser rekursiven Antworten die richtige Antwort sein sollte. Die akzeptierte Antwort enthält keinen Code und ist nicht hilfreich

8voto

Adriano Spadoni Punkte 3967

ES6: Der minimale Code, den ich hinbekommen könnte, ist dieser. Es tun tiefe Vergleich rekursiv durch stringifying alle Schlüssel-Wert-Array sortiert, die das Objekt, die einzige Einschränkung ist keine Methoden oder Symbole zu vergleichen sind.

const compareObjects = (a, b) => { 
  let s = (o) => Object.entries(o).sort().map(i => { 
     if(i[1] instanceof Object) i[1] = s(i[1]);
     return i 
  }) 
  return JSON.stringify(s(a)) === JSON.stringify(s(b))
}

console.log(compareObjects({b:4,a:{b:1}}, {a:{b:1},b:4}));

WICHTIG! Diese Funktion führt einen JSON.stringfy in einer ARRAY mit den sortierten Schlüsseln und PAS in dem Objekt selbst:

  1. ["a", ["b", 1]]
  2. ["b", 4]

0 Stimmen

Dies ist eine voll funktionsfähige Antwort, danke @Adriano Spadoni. Wissen Sie, wie ich den Schlüssel/das Attribut erhalten kann, der/das geändert wurde? Danke!

1 Stimmen

Hallo @digital, wenn Sie wissen wollen, welche Tasten unterschiedlich sind, ist dies nicht die ideale Funktion. Prüfen Sie die andere Antwort und verwenden Sie eine mit einer Schleife durch die Objekte.

0 Stimmen

Verwenden Sie niemals JSON.stringify, um json-Objekte zu vergleichen. Es wird nicht erwartet, dass die Reihenfolge der Schlüssel gleich ist.

6voto

Paul Punkte 4796

Nachfolgend finden Sie eine kurze Implementierung, bei der JSON.stringify aber sortiert die Schlüssel wie von @Jor vorgeschlagen aquí .

Einige Tests wurden aus der Antwort von @EbrahimByagowi übernommen aquí .

Natürlich, durch die Verwendung von JSON.stringify ist die Lösung auf JSON-serialisierbare Typen beschränkt (eine Zeichenkette, eine Zahl, ein JSON-Objekt, ein Array, ein Boolean, null). Objekte wie Date , Function usw. werden nicht unterstützt.

function objectEquals(obj1, obj2) {
  const JSONstringifyOrder = obj => {
    const keys = {};
    JSON.stringify(obj, (key, value) => {
      keys[key] = null;
      return value;
    });
    return JSON.stringify(obj, Object.keys(keys).sort());
  };
  return JSONstringifyOrder(obj1) === JSONstringifyOrder(obj2);
}

///////////////////////////////////////////////////////////////
/// The borrowed tests, run them by clicking "Run code snippet"
///////////////////////////////////////////////////////////////
var printResult = function (x) {
    if (x) { document.write('<div style="color: green;">Passed</div>'); }
    else { document.write('<div style="color: red;">Failed</div>'); }
};
var assert = { isTrue: function (x) { printResult(x); }, isFalse: function (x) { printResult(!x); } }

assert.isTrue(objectEquals("hi","hi"));
assert.isTrue(objectEquals(5,5));
assert.isFalse(objectEquals(5,10));

assert.isTrue(objectEquals([],[]));
assert.isTrue(objectEquals([1,2],[1,2]));
assert.isFalse(objectEquals([1,2],[2,1]));
assert.isFalse(objectEquals([1,2],[1,2,3]));

assert.isTrue(objectEquals({},{}));
assert.isTrue(objectEquals({a:1,b:2},{a:1,b:2}));
assert.isTrue(objectEquals({a:1,b:2},{b:2,a:1}));
assert.isFalse(objectEquals({a:1,b:2},{a:1,b:3}));

assert.isTrue(objectEquals({1:{name:"mhc",age:28}, 2:{name:"arb",age:26}},{1:{name:"mhc",age:28}, 2:{name:"arb",age:26}}));
assert.isFalse(objectEquals({1:{name:"mhc",age:28}, 2:{name:"arb",age:26}},{1:{name:"mhc",age:28}, 2:{name:"arb",age:27}}));

4voto

Können Sie _.isEqual(obj1, obj2) aus der underscore.js-Bibliothek.

Hier ist ein Beispiel:

var stooge = {name: 'moe', luckyNumbers: [13, 27, 34]};
var clone  = {name: 'moe', luckyNumbers: [13, 27, 34]};
stooge == clone;
=> false
_.isEqual(stooge, clone);
=> true

Die offizielle Dokumentation finden Sie hier: http://underscorejs.org/#isEqual

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X