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

2voto

mckoss Punkte 6444

Es ist sinnvoll, zwei Objekte als gleich zu betrachten, wenn sie für alle Eigenschaften und rekursiv für alle verschachtelten Objekte und Arrays die gleichen Werte haben. Ich betrachte auch die folgenden zwei Objekte als gleich:

var a = {p1: 1};
var b = {p1: 1, p2: undefined};

In ähnlicher Weise können Arrays "fehlende" und undefinierte Elemente enthalten. Ich würde auch diese gleich behandeln:

var c = [1, 2];
var d = [1, 2, undefined];

Eine Funktion, die diese Definition von Gleichheit implementiert:

function isEqual(a, b) {
    if (a === b) {
        return true;
    }

    if (generalType(a) != generalType(b)) {
        return false;
    }

    if (a == b) {
        return true;
    }

    if (typeof a != 'object') {
        return false;
    }

    // null != {}
    if (a instanceof Object != b instanceof Object) {
        return false;
    }

    if (a instanceof Date || b instanceof Date) {
        if (a instanceof Date != b instanceof Date ||
            a.getTime() != b.getTime()) {
            return false;
        }
    }

    var allKeys = [].concat(keys(a), keys(b));
    uniqueArray(allKeys);

    for (var i = 0; i < allKeys.length; i++) {
        var prop = allKeys[i];
        if (!isEqual(a[prop], b[prop])) {
            return false;
        }
    }
    return true;
}

Quellcode (einschließlich der Hilfsfunktionen, generalType und uniqueArray): Einheitstest y Test Runner hier .

2voto

Haseeb Butt Punkte 57

beide Objekte stringifizieren und vergleichen

if(JSON.stringify(object1) == JSON.stringify(object2))
{
true, wenn beide dasselbe Objekt
}
sonst
{
false, wenn nicht dasselbe Objekt
}

0 Stimmen

Ob1 = {"Alter": 1, "Name": "a" } ob2 = {"name": "a", "Alter": 1} JSON.stringify(ob1) == JSON.stringify(ob2) // FALSE

9 Stimmen

Die Reihenfolge der Eigenschaften ist wichtig

2voto

Oliver Dixon Punkte 6507

Ich sehe Spaghetti-Code-Antworten. Ohne die Verwendung von Drittanbieter-Libs, ist dies sehr einfach.

Sortieren Sie zunächst die beiden Objekte nach ihren Schlüsselnamen.

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)

Verwenden Sie dann einfach eine Zeichenkette, um sie zu vergleichen.

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

1 Stimmen

Dies funktioniert auch nicht für Deep Copy, es hat nur eine Iterationstiefe.

0 Stimmen

Ich denke, @andras meint, dass Sie die Schlüssel von verschachtelten Objekten rekursiv sortieren müssen.

0 Stimmen

@eksapsy unterschiedliche Probleme haben unterschiedliche Lösungen. Lesbarkeit übertrumpft bei der Programmierung immer die Leistung, obwohl wir heute auf modernen Systemen den Speicher schonen können, Optimierungen sind die Wurzel des Übels bei der Programmierung. Ich bin sicher, wenn Sie "riesige" Objekte haben, dann ist die gesamte Architektur wahrscheinlich falsch; Sie sollten dann etwas wie Elastic für große JSON-Sammlungen in Betracht ziehen. Es gibt viele verschiedene Lösungen für dieses Problem, ich bin sicher, es könnte besser sein, ich habe das vor Jahren in aller Eile geschrieben.

2voto

Bernard Igiri Punkte 1272

Ich würde von Hashing oder Serialisierung abraten (wie es die JSON-Lösung vorschlägt). Wenn Sie testen müssen, ob zwei Objekte gleich sind, dann müssen Sie definieren, was gleich bedeutet. Es könnte sein, dass alle Datenelemente in beiden Objekten übereinstimmen, oder es könnte sein, dass die Speicherorte übereinstimmen müssen (was bedeutet, dass beide Variablen auf das gleiche Objekt im Speicher verweisen), oder es könnte sein, dass nur ein Datenelement in jedem Objekt übereinstimmen muss.

Vor kurzem habe ich ein Objekt entwickelt, dessen Konstruktor jedes Mal, wenn eine Instanz erstellt wird, eine neue ID (beginnend mit 1 und um 1 erhöht) erzeugt. Dieses Objekt hat eine isEqual-Funktion, die diesen id-Wert mit dem id-Wert eines anderen Objekts vergleicht und true zurückgibt, wenn sie übereinstimmen.

In diesem Fall habe ich "gleich" so definiert, dass die ID-Werte übereinstimmen. Da jede Instanz eine eindeutige ID hat, könnte dies verwendet werden, um die Idee durchzusetzen, dass übereinstimmende Objekte auch denselben Speicherplatz belegen. Das ist allerdings nicht notwendig.

2voto

Lex Punkte 2458

Dies ist ein Zusatz für alle oben genannten, nicht ein Ersatz. Wenn Sie einen schnellen, flachen Vergleich von Objekten benötigen, ohne dass Sie zusätzliche rekursive Fälle prüfen müssen. Hier ist ein Schuss.

Es wird verglichen auf: 1) Gleichheit der Anzahl der eigenen Eigenschaften, 2) Gleichheit der Schlüsselnamen, 3) wenn bCompareValues == true, Gleichheit der entsprechenden Eigenschaftswerte und ihrer Typen (dreifache Gleichheit)

var shallowCompareObjects = function(o1, o2, bCompareValues) {
    var s, 
        n1 = 0,
        n2 = 0,
        b  = true;

    for (s in o1) { n1 ++; }
    for (s in o2) { 
        if (!o1.hasOwnProperty(s)) {
            b = false;
            break;
        }
        if (bCompareValues && o1[s] !== o2[s]) {
            b = false;
            break;
        }
        n2 ++;
    }
    return b && n1 == n2;
}

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