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?"

27voto

nickf Punkte 517253

Versuchen Sie zu testen, ob zwei Objekte gleich sind, d.h. ob ihre Eigenschaften gleich sind?

Wenn dies der Fall ist, werden Sie diese Situation wahrscheinlich bemerkt haben:

var a = { foo : "bar" };
var b = { foo : "bar" };
alert (a == b ? "Equal" : "Not equal");
// "Not equal"

müssen Sie vielleicht so vorgehen:

function objectEquals(obj1, obj2) {
    for (var i in obj1) {
        if (obj1.hasOwnProperty(i)) {
            if (!obj2.hasOwnProperty(i)) return false;
            if (obj1[i] != obj2[i]) return false;
        }
    }
    for (var i in obj2) {
        if (obj2.hasOwnProperty(i)) {
            if (!obj1.hasOwnProperty(i)) return false;
            if (obj1[i] != obj2[i]) return false;
        }
    }
    return true;
}

Natürlich könnte diese Funktion ein wenig optimiert werden und die Möglichkeit bieten, eine Tiefenprüfung durchzuführen (um verschachtelte Objekte zu behandeln): var a = { foo : { fu : "bar" } } ), aber Sie können sich das vorstellen.

Wie FOR bereits erwähnt hat, müssen Sie dies möglicherweise für Ihre eigenen Zwecke anpassen, z. B. können verschiedene Klassen unterschiedliche Definitionen von "gleich" haben. Wenn Sie nur mit einfachen Objekten arbeiten, kann das oben Gesagte ausreichen, andernfalls kann eine eigene MyClass.equals() Funktion kann der richtige Weg sein.

0 Stimmen

Es ist eine lange Methode, aber sie testet die Objekte vollständig, ohne Annahmen über die Reihenfolge der Eigenschaften in jedem Objekt zu treffen.

0 Stimmen

Funktioniert nicht, wenn eine Eigenschaft ein Array von anderen Objekten ist

24voto

Ates Goral Punkte 132294

Wenn Sie eine Deep-Copy-Funktion zur Hand haben, können Sie den folgenden Trick anwenden, um immer noch verwenden. JSON.stringify wobei die Reihenfolge der Eigenschaften übereinstimmt:

function equals(obj1, obj2) {
    function _equals(obj1, obj2) {
        return JSON.stringify(obj1)
            === JSON.stringify($.extend(true, {}, obj1, obj2));
    }
    return _equals(obj1, obj2) && _equals(obj2, obj1);
}

Demo: http://jsfiddle.net/CU3vb/3/

Begründung:

Da die Eigenschaften von obj1 nacheinander in den Klon kopiert werden, bleibt ihre Reihenfolge im Klon erhalten. Und wenn die Eigenschaften von obj2 werden in den Klon kopiert, da Eigenschaften, die bereits in obj1 werden einfach überschrieben, ihre Reihenfolge im Klon bleibt erhalten.

11 Stimmen

Ich glaube nicht, dass die Beibehaltung der Reihenfolge in allen Browsern/Engines gewährleistet ist.

0 Stimmen

@JoLiss Zitate erforderlich ;) Ich erinnere mich, dass ich dies in mehreren Browsern getestet habe und dabei konsistente Ergebnisse erhielt. Aber natürlich kann niemand garantieren, dass das Verhalten in zukünftigen Browsern/Engines gleich bleibt. Dies ist bestenfalls ein Trick (wie bereits in der Antwort erwähnt), und ich wollte damit keine todsichere Methode zum Vergleich von Objekten bieten.

1 Stimmen

Sicher, hier sind einige Hinweise: Laut ECMAScript-Spezifikation ist das Objekt "ungeordnet". und diese Antwort für das tatsächliche abweichende Verhalten auf aktuellen Browsern.

24voto

Pratik Bhalodiya Punkte 646

Einfachste y logisch Lösungen für den Vergleich von allem Wie Objekt, Array, String, Int...

JSON.stringify({a: val1}) === JSON.stringify({a: val2})

Note :

  • müssen Sie ersetzen val1 et val2 mit Ihrem Objekt
  • für das Objekt müssen Sie für beide Seitenobjekte rekursiv sortieren (nach Schlüssel)

12 Stimmen

Ich gehe davon aus, dass dies in vielen Fällen nicht funktionieren wird, weil die Reihenfolge der Schlüssel in den Objekten keine Rolle spielt - es sei denn JSON.stringify eine alphabetische Neuordnung vornimmt? (Was ich nicht finden kann dokumentiert .)

0 Stimmen

Ja, Sie haben Recht ... für das Objekt, müssen Sie rekursiv für beide Seiten Objekte zu sortieren

6 Stimmen

Dies funktioniert nicht bei Objekten mit zirkulären Referenzen

22voto

Aqeel Bahoo Punkte 307
var object1 = {name: "humza" , gender : "male", age: 23}
var object2 = {name: "humza" , gender : "male", age: 23}
var result = Object.keys(object1).every((key) =>  object1[key] === object2[key])

Das Ergebnis wird sein wahr wenn Objekt1 dieselben Werte wie Objekt2 hat.

5 Stimmen

Dies funktioniert nicht, wenn object2 zusätzliche Schlüssel hat, die object1 nicht enthält.

0 Stimmen

Wie @Ram Kumar erwähnt wird dies nur funktionieren, wenn Sie Schleife beide Objekte, nicht sehr effizient, aber für kleine Objekte, die ich denke, es wird schneller die Verkettung der Objekte - nicht 100% sicher aber

0 Stimmen

@RamKumar fügen Sie einfach die Bedingung ein var result = Object.keys(object1).every((key) =>(object1[key] === object2[key] && object1.hasOwnProperty(key) && object2.hasOwnProperty(key))

16voto

jib Punkte 37095

Ich benutze diese comparable Funktion, um Kopien meiner Objekte zu erstellen, die mit JSON vergleichbar sind:

var comparable = o => (typeof o != 'object' || !o)? o :
  Object.keys(o).sort().reduce((c, key) => (c[key] = comparable(o[key]), c), {});

// Demo:

var a = { a: 1, c: 4, b: [2, 3], d: { e: '5', f: null } };
var b = { b: [2, 3], c: 4, d: { f: null, e: '5' }, a: 1 };

console.log(JSON.stringify(comparable(a)));
console.log(JSON.stringify(comparable(b)));
console.log(JSON.stringify(comparable(a)) == JSON.stringify(comparable(b)));

<div id="div"></div>

Ist bei Tests sehr nützlich (die meisten Test-Frameworks haben eine is Funktion). z.B.

is(JSON.stringify(comparable(x)), JSON.stringify(comparable(y)), 'x must match y');

Wenn ein Unterschied festgestellt wird, werden die Zeichenfolgen protokolliert, so dass die Unterschiede erkennbar sind:

x must match y
got      {"a":1,"b":{"0":2,"1":3},"c":7,"d":{"e":"5","f":null}},
expected {"a":1,"b":{"0":2,"1":3},"c":4,"d":{"e":"5","f":null}}.

1 Stimmen

Gute Idee (in meinem Fall sind die zu vergleichenden Objekte nur Schlüssel/Wert-Paare, keine besonderen Dinge)

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