Zur Zeit folge ich einem Buch und bin schwer verwirrt und habe versucht, den folgenden Code mehrmals zu verstehen. Meine erste Verwirrung nähert sich tatsächlich dem Problem des Vergleichens zweier Objekte a und b .
%Vor% Zuerst überprüfen wir, ob a
und b
genau gleich sind (was bedeutet, dass "sich auf genau die gleiche Sache bezieht" ). Die meisten Dinge, wie Strings und Zahlen, bestehen diesen Test, wenn sie gleich sind; Objekte sind die Ausnahme, da zwei "identische" Objekte nicht unbedingt das gleiche Objekt sein müssen (sie können einfach gleich aussehen).
Dann sagen wir, dass, wenn eines der beiden Objekte kein Objekt ist und sie den letzten Test nicht bestanden haben, sie nicht gleich sein können. Auch hier sind Objekte die Ausnahme, so dass der verbleibende Code für den Fall sorgt, dass a
und b
beide Objekte sind.
Dieser Code zählt einfach die Anzahl der Eigenschaften von a
.
Dieser Code übernimmt jede Eigenschaft in b
und überprüft, ob a
dieselbe Eigenschaft mit demselben Wert enthält. Wenn a
keine Eigenschaft hat, die b
hat, oder sie unterschiedlich sind, dann können die beiden Objekte nicht gleich sein.
Schließlich, wenn a
und b
nicht die gleiche Anzahl von Eigenschaften haben, können sie nicht gleich sein. Wenn sie jedoch die gleiche Anzahl an Eigenschaften haben, müssen a
und b
gleich sein, da a
alle Eigenschaften hat, die b
hat, und nur die .
Ich werde Sie durchgehen.
%Vor%Wir prüfen, ob es sich um die gleiche Sache handelt, wir kommen später wieder hierher.
%Vor%Wir prüfen, ob eines oder keines dieser Dinge Objekte definiert sind. Wir kommen auch hier zurück.
Behalten Sie diese ersten beiden Snippets im Hinterkopf, sie kommen erst ins Spiel, wenn wir die Funktion rekursiv aufrufen.
%Vor%Diese werden verwendet, um die Anzahl der Eigenschaften in Objekt A und B zu verfolgen.
%Vor%Wir haben zwei for-Schleifen. Der erste durchläuft einfach alle Eigenschaften in A (suche nach ... in Syntax, wenn du nicht vertraut bist), und für jeden erhöht sich die Variable requisitenInA.
Die zweite Schleife macht dasselbe für B, aber hier wird es komplizierter. Zuerst prüft es, ob diese Eigenschaft in A existiert, oder ob deepequal wahr zurückgibt. Hier kommen die ersten beiden Snippets ins Spiel, die wir untersucht haben. Das erste Snippet wird hier verwendet, um true zurückzugeben, wenn die Eigenschaften, die wir ihm geben, gleich sind. Der zweite Ausschnitt sagt "Wenn wir Eigenschaften anstelle von Funktionen übergeben haben, höre hier auf". Dies ist wichtig, da diese Funktion hier nur dann ausgeführt werden muss, wenn es sich um den ersten Aufruf handelt. Alle rekursiven Aufrufe müssen nur den ersten Teil verwenden. Wenn einer dieser beiden Werte false zurückgibt, geben wir false zum ersten Aufruf zurück, weil wir wissen, dass zwischen A und B ein Unterschied besteht.
%Vor%Wir können hier nicht wahr werden, weil wir eigentlich nicht wissen, ob es in B etwas weniger Eigenschaften gibt. Obwohl alles andere gleich aussieht, können wir nicht davon ausgehen, dass sie die gleiche Menge an Eigenschaften haben. Dies stellt als letzte Prüfung sicher, dass wir nur dann true zurückgeben, wenn die Anzahl der Eigenschaften in A gleich der Anzahl in B
istFühlen Sie sich frei, mich zu bitten, weiter zu erklären.
Bei dieser Funktion
true
. typeof a! = "object"
- Das überprüft, ob der Typ der Parameter (a und b) Objekte sind. Wenn eine davon kein Objekt ist, endet die Funktion mit der Rückgabe von false
. propsInA
für a zählt und propsInB
für b entsprechend. propsInA
und propsInB
vergleichen, wenn sie identisch sind, endet die Funktion mit der Rückgabe von true
andernfalls wird false
zurückgegeben. Ihr Algorithmus verhält sich so:
Wenn a
und b
genau gleich sind, geben Sie true
a
und b
gelten als genau gleich, wenn eine der folgenden Bedingungen zutrifft:
NaN
+0
und -0
(oder umgekehrt) Dies geschieht mit dem strikten Gleichheitsvergleichsoperator ( ===
).
Wenn entweder a
oder b
oder beide Objekte nicht als Objekte betrachtet werden, geben Sie false
o
wird nicht als Objekt betrachtet, wenn eine der folgenden Bedingungen zutrifft:
o
ist ein primitiver Wert o
gehört zum Objekttyp, hat aber eine interne Methode [[Call]]. Das heißt, ist ein aufrufbares Objekt, z.B. eine Funktion oder ein HTML <object>
-Element. o
ist ein nicht aufrufbares nicht standardmäßiges exotisches Objekt, dessen vom typeof
-Operator zurückgegebene implementierungsdefinierte Prozedur sich von "object
'' unterscheidet. Dies geschieht mit dem Operator typeof
, der eine Zeichenfolge mit dem Typ des Werts zurückgibt, mit Ausnahme von null
und möglicherweise Objekten. Seit typeof null === "object"
, a == null
ist überprüft.
Wenn a
und b
eine andere Anzahl aufzählbarer Eigenschaften haben (unter Berücksichtigung von eigenen und geerbten Eigenschaften), geben Sie false
zurück.
Dies wird von propsInA
und propsInB
gezählt.
Wenn b
eine aufzählbare (eigene oder geerbte) Eigenschaft hat, aber a
keine (nicht aufzählbare oder aufzählbare, eigene oder geerbte, nicht unbedingt dieselbe b
) Eigenschaft mit demselben Namen hat , return false
.
Dies geschieht durch Iteration von for (var prop in b)
und Überprüfung von prop in a
.
Wenn b
eine aufzählbare (eigene oder geerbte) Eigenschaft hat, deren Wert vom Algorithmus deepEqual
als unterschiedlich angesehen wird, als der Wert derselben Eigenschaft in a
, geben Sie false
zurück.
Dies geschieht durch Iteration von for (var prop in b)
und Überprüfung von deepEqual(a[prop], b[prop])
.
Andernfalls geben Sie true
zurück.
Ich glaube nicht, dass es ein guter Algorithmus ist. Zum Beispiel betrachtet es {}
, Object.prototype
und Object.create(null)
als alle gleich, aber ich würde das nicht sagen.
Tags und Links javascript