1020 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

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

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

4voto

Ich habe eine einfache Möglichkeit gefunden, die Werte von zwei Javascript-Objekten ohne Berücksichtigung der Eigentumsordnung ist mit der Funktion JSON stringify replacer:

const compareReplacer = (key, value) => {
    if(typeof value === 'object' && !(value instanceof Array))
        return Object.entries(value).sort();
    return value;
}
export const compareObjects = (a, b) => JSON.stringify(a, compareReplacer) === JSON.stringify(b, compareReplacer);

Dadurch werden die Eigenschaften bei jedem Schritt geordnet, so dass das Ergebnis der Zeichenkette nicht von der Reihenfolge der Eigenschaften abhängt. Jemand hat wahrscheinlich dies vor getan, aber ich dachte nur, ich würde es teilen, falls nicht :).

3voto

Sir_baaron Punkte 325

Ich stand vor demselben Problem und beschloss, meine eigene Lösung zu schreiben. Da ich aber auch Arrays mit Objekten und umgekehrt vergleichen möchte, habe ich eine generische Lösung entwickelt. Ich beschloss, die Funktionen zum Prototyp hinzuzufügen, aber man kann sie leicht in eigenständige Funktionen umschreiben. Hier ist der Code:

Array.prototype.equals = Object.prototype.equals = function(b) {
    var ar = JSON.parse(JSON.stringify(b));
    var err = false;
    for(var key in this) {
        if(this.hasOwnProperty(key)) {
            var found = ar.find(this[key]);
            if(found > -1) {
                if(Object.prototype.toString.call(ar) === "[object Object]") {
                    delete ar[Object.keys(ar)[found]];
                }
                else {
                    ar.splice(found, 1);
                }
            }
            else {
                err = true;
                break;
            }
        }
    };
    if(Object.keys(ar).length > 0 || err) {
        return false;
    }
    return true;
}

Array.prototype.find = Object.prototype.find = function(v) {
    var f = -1;
    for(var i in this) {
        if(this.hasOwnProperty(i)) {
            if(Object.prototype.toString.call(this[i]) === "[object Array]" || Object.prototype.toString.call(this[i]) === "[object Object]") {
                if(this[i].equals(v)) {
                    f = (typeof(i) == "number") ? i : Object.keys(this).indexOf(i);
                }
            }
            else if(this[i] === v) {
                f = (typeof(i) == "number") ? i : Object.keys(this).indexOf(i);
            }
        }
    }
    return f;
}

Dieser Algorithmus besteht aus zwei Teilen: der Gleichheitsfunktion selbst und einer Funktion zum Auffinden des numerischen Index einer Eigenschaft in einem Array/Objekt. Die find-Funktion wird nur benötigt, weil indexof nur Zahlen und Strings und keine Objekte findet.

Man kann es auch so nennen:

({a: 1, b: "h"}).equals({a: 1, b: "h"});

Die Funktion gibt entweder true oder false zurück, in diesem Fall true. Der Algorithmus ermöglicht auch den Vergleich zwischen sehr komplexen Objekten:

({a: 1, b: "hello", c: ["w", "o", "r", "l", "d", {answer1: "should be", answer2: true}]}).equals({b: "hello", a: 1, c: ["w", "d", "o", "r", {answer1: "should be", answer2: true}, "l"]})

Das obere Beispiel gibt true zurück, auch wenn die Eigenschaften eine andere Reihenfolge haben. Ein kleines Detail, auf das Sie achten sollten: Dieser Code prüft auch, ob zwei Variablen den gleichen Typ haben, also ist "3" nicht dasselbe wie 3.

3voto

Mirek Rusin Punkte 17854

Wenn Sie JSON-Objekte vergleichen, können Sie https://github.com/mirek/node-rus-diff

npm install rus-diff

使用方法

a = {foo:{bar:1}}
b = {foo:{bar:1}}
c = {foo:{bar:2}}

var rusDiff = require('rus-diff').rusDiff

console.log(rusDiff(a, b)) // -> false, meaning a and b are equal
console.log(rusDiff(a, c)) // -> { '$set': { 'foo.bar': 2 } }

Wenn zwei Objekte unterschiedlich sind, wird eine MongoDB-kompatible {$rename:{...}, $unset:{...}, $set:{...}} wie ein Objekt zurückgegeben.

3voto

xameeramir Punkte 25274

Vorausgesetzt, dass die Reihenfolge der Eigenschaften im Objekt nicht geändert wird.

JSON.stringify() funktioniert sowohl für tiefe als auch für nicht-tiefe Objekttypen, wobei die Leistungsaspekte nicht ganz klar sind:

var object1 = {
  key: "value"
};

var object2 = {
  key: "value"
};

var object3 = {
  key: "no value"
};

console.log('object1 and object2 are equal: ', JSON.stringify(object1) === JSON.stringify(object2));

console.log('object2 and object3 are equal: ', JSON.stringify(object2) === JSON.stringify(object3));

1 Stimmen

Dies entspricht nicht den Wünschen des Auftraggebers, da es nur dann zu einer Übereinstimmung kommt, wenn beide Objekte die gleichen Schlüssel haben, was nicht der Fall ist. Es würde auch erfordern, dass die Schlüssel in der gleichen Reihenfolge sein, die auch nicht wirklich sinnvoll ist.

3 Stimmen

Was ist, wenn die Eigenschaften in unterschiedlicher Reihenfolge sind? Nein, das ist keine gute Methode

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