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

0voto

Randhir Rawatlal Punkte 195

Reiner JS-Ansatz : Meine Antwort basiert auf der Generierung einer Zeichenkette, die unabhängig von der Reihenfolge der Attribute den gleichen Wert liefert. Das Einstellungsobjekt kann verwendet werden, um die Groß- und Kleinschreibung und das Vorhandensein von Leerzeichen zu berücksichtigen. (Um zu vermeiden, dass ich den Fokus verliere, schließe ich diese Unterstützungsfunktionen nicht mit ein, ebenso wenig wie isObject, das wohl in jedem Utility-Set enthalten sein sollte).

Auch hier nicht gezeigt, aber um die String-Vergleichszeit zu reduzieren, wenn die Objekte groß sind und Sie den Vergleich beschleunigen möchten, könnten Sie auch die Strings hashen und Teilstrings vergleichen; dies würde nur bei sehr großen Objekten Sinn machen (und natürlich eine kleine Chance auf falsche Gleichheit).

Sie können dann einfach vergleichen genObjStr(obj1) ?= genObjStr(obj2)

function genObjStr(obj, settings) {
// Generate a string that corresponds to an object guarenteed to be the same str even if
// the object have different ordering. The string would largely be used for comparison purposes

var settings = settings||{};
var doStripWhiteSpace = defTrue(settings.doStripWhiteSpace);
var doSetLowerCase = settings.doSetLowerCase||false;

if(isArray(obj)) {
    var vals = [];
    for(var i = 0; i < obj.length; ++i) {
        vals.push(genObjStr(obj[i], settings));
    }
    vals = arraySort(vals);
    return vals.join(`,`);

} else if(isObject(obj)) {

    var keys = Object.keys(obj);
    keys = arraySort(keys);

    var vals = [];
    for(var key of keys) {

        var value = obj[key];

        value = genObjStr(value, settings);

        if(doStripWhiteSpace) {
            key = removeWhitespace(key);
            var value = removeWhitespace(value);
        };
        if(doSetLowerCase) {
            key = key.toLowerCase();
            value = value.toLowerCase();
        }

        vals.push(value);
    }
    var str = JSON.stringify({keys: keys, vals: vals});
    return str
} else {
    if(doStripWhiteSpace) {
        obj = removeWhitespace(obj);
    };
    if(doSetLowerCase) {
        obj = obj.toLowerCase();
    }
    return obj
}

}

var obj1 = {foo: 123, bar: `Test`};
var obj2 = {bar: `Test`, foo: 123};

console.log(genObjStr(obj1) == genObjStr(obj1))

0voto

YassBan Punkte 29

Wenn Ihre Frage darin besteht, zu prüfen, ob zwei Objekte gleich sind, könnte diese Funktion nützlich sein

function equals(a, b) {
const aKeys = Object.keys(a)
const bKeys = Object.keys(b)
if(aKeys.length != bKeys.length) {
    return false
}
for(let i = 0;i < aKeys.length;i++) {
    if(aKeys[i] != bKeys[i]) {
        return false
    } 
}
for(let i = 0;i < aKeys.length;i++) {
    if(a[aKeys[i]] != b[bKeys[i]]) {
        return false
    }
}
return true
}

zuerst wird geprüft, ob die Länge der Liste der Schlüssel dieser Objekte gleich ist, wenn nicht, wird false zurückgegeben um zu prüfen, ob zwei Objekte gleich sind, müssen sie die gleichen Schlüssel (=Namen) und die gleichen Werte der Schlüssel haben, also holen wir uns alle Schlüssel von objA und objB und prüfen dann, ob sie gleich sind, wenn wir feststellen, dass zwei Schlüssel nicht gleich sind, geben wir false zurück Wenn alle Schlüssel gleich sind, gehen wir in einer Schleife durch einen der Schlüssel eines der Objekte und prüfen, ob sie gleich sind. Wenn sie nicht gleich sind, geben wir false zurück. HINWEIS: Diese Funktion funktioniert nur bei Objekten ohne Funktionen

0voto

Dakusan Punkte 6255

Meine Version, die die Kette enthält, in der der Unterschied zu finden ist und worin der Unterschied besteht.

function DeepObjectCompare(O1, O2)
{
    try {
        DOC_Val(O1, O2, ['O1->O2', O1, O2]);
        return DOC_Val(O2, O1, ['O2->O1', O1, O2]);
    } catch(e) {
        console.log(e.Chain);
        throw(e);
    }
}
function DOC_Error(Reason, Chain, Val1, Val2)
{
    this.Reason=Reason;
    this.Chain=Chain;
    this.Val1=Val1;
    this.Val2=Val2;
}

function DOC_Val(Val1, Val2, Chain)
{
    function DoThrow(Reason, NewChain) { throw(new DOC_Error(Reason, NewChain!==undefined ? NewChain : Chain, Val1, Val2)); }

    if(typeof(Val1)!==typeof(Val2))
        return DoThrow('Type Mismatch');
    if(Val1===null || Val1===undefined)
        return Val1!==Val2 ? DoThrow('Null/undefined mismatch') : true;
    if(Val1.constructor!==Val2.constructor)
        return DoThrow('Constructor mismatch');
    switch(typeof(Val1))
    {
        case 'object':
            for(var m in Val1)
            {
                if(!Val1.hasOwnProperty(m))
                    continue;
                var CurChain=Chain.concat([m]);
                if(!Val2.hasOwnProperty(m))
                    return DoThrow('Val2 missing property', CurChain);
                DOC_Val(Val1[m], Val2[m], CurChain);
            }
            return true;
        case 'number':
            if(Number.isNaN(Val1))
                return !Number.isNaN(Val2) ? DoThrow('NaN mismatch') : true;
        case 'string':
        case 'boolean':
            return Val1!==Val2 ? DoThrow('Value mismatch') : true;
        case 'function':
            if(Val1.prototype!==Val2.prototype)
                return DoThrow('Prototype mismatch');
            if(Val1!==Val2)
                return DoThrow('Function mismatch');
            return true;
        default:
            return DoThrow('Val1 is unknown type');
    }
}

0voto

Dude Punkte 189

Dies ist eine einfache Javascript-Funktion zum Vergleich zweier Objekte mit einfachen Schlüssel-Wert-Paaren. Die Funktion gibt ein Array von Strings zurück, wobei jeder String ein Pfad zu einer Ungleichheit zwischen den beiden Objekten ist.

function compare(a,b) {
    var paths = [];
    [...new Set(Object.keys(a).concat(Object.keys(b)))].forEach(key=>{
        if(typeof a[key] === 'object' && typeof b[key] === 'object') {
            var results = compare(a[key], b[key]);
            if(JSON.stringify(results)!=='[]') {
                paths.push(...results.map(result=>key.concat("=>"+result)));
            }
        }
        else if (a[key]!==b[key]) {
            paths.push(key);
        }
    })
    return paths;
}

Wenn Sie nur zwei Objekte vergleichen wollen, ohne die Pfade zu den Ungleichungen zu kennen, können Sie dies wie folgt tun:

if(JSON.stringify(compare(object1, object2))==='[]') {
   // the two objects are equal
} else {
   // the two objects are not equal
}

0voto

ashuvssut Punkte 752

Die Verwendung von JSON.stringify() ist nicht immer zuverlässig . Diese Methode ist also die beste Lösung für Ihre Frage IMO

Zuallererst, Nein gibt es kein allgemeines Mittel, um festzustellen, dass ein Objekt gleich ist!

Aber es gibt ein Konzept namens Shallow Equality Vergleich . Es gibt eine npm-Bibliothek die Ihnen helfen können, dieses Konzept zu nutzen

Beispiel

const shallowequal = require('shallowequal');

const object = { 'user': 'fred' };
const other = { 'user': 'fred' };

// Referential Equality Comparison (`strict ===`)
object === other; //  false

// Shallow Equality Comparison
shallowequal(object, other); //  true

Wenn Sie wissen möchten, wie Sie shallowEqual Vergleichsmethode, dann siehe aquí . Seine von der OpenSource fbjs Facebook-Bibliothek.


Seichter Gleichheitsvergleich

shallowequal(obj1, obj2)

shallowEqual Führt einen oberflächlichen Gleichheitsvergleich zwischen zwei Werten durch (d. h. obj1 y obj2 ), um festzustellen, ob sie gleichwertig sind.

Die Gleichheit wird durch Iteration über die Schlüssel der angegebenen obj1 und die Rückkehr false wenn ein Schlüssel Werte hat, die nicht genau gleich sind zwischen obj1 y obj2 . Andernfalls wird true wenn die Werte aller Schlüssel genau gleich sind.

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