Ich muss einige Experimente durchführen und eine eindeutige Kennung für Objekte in Javascript kennen, damit ich sehen kann, ob sie identisch sind. Ich möchte keine Gleichheitsoperatoren verwenden, ich brauche so etwas wie die Funktion id () in Python.
Gibt es so etwas?
javascript
Stefano Borini
quelle
quelle
Antworten:
Update Meine ursprüngliche Antwort unten wurde vor 6 Jahren in einem Stil geschrieben, der der Zeit und meinem Verständnis entspricht. Als Reaktion auf einige Gespräche in den Kommentaren lautet ein moderner Ansatz wie folgt:
Wenn Sie archaische Browseranforderungen haben, überprüfen Sie hier die Browserkompatibilität für
Object.defineProperty
.Die ursprüngliche Antwort wird unten aufbewahrt (anstatt nur in der Änderungshistorie), da ich den Vergleich für wertvoll halte.
Sie können Folgendes ausprobieren. Dies gibt Ihnen auch die Möglichkeit, die ID eines Objekts explizit in seinem Konstruktor oder anderswo festzulegen.
Stellen Sie sicher, dass das Mitglied, mit dem Sie die eindeutige ID intern speichern, nicht mit einem anderen automatisch erstellten Mitgliedsnamen kollidiert.
quelle
object.hasOwnProperty(member)
einefor..in
Schleife zu verwenden. Dies ist eine gut dokumentierte Praxis, die von jslint durchgesetzt wirddefineProperty(…, {enumerable:false})
. Und dieuid
Methode selbst sollteObject
sowieso im Namespace sein4
wie würden Sie dann einer Variablen obj mit der ID 4 zuweisen, damit Sie damit etwas anfangen können ... wie auf seine Eigenschaften zugreifen?Nach meiner Beobachtung kann jede hier veröffentlichte Antwort unerwartete Nebenwirkungen haben.
In einer ES2015-kompatiblen Umgebung können Sie mithilfe von WeakMap Nebenwirkungen vermeiden .
quelle
return currentId
?WeakMap
im Gegensatz zuMap
? Diese Funktion stürzt ab, wenn Sie eine Zeichenfolge oder Nummer eingeben.Die neuesten Browser bieten eine übersichtlichere Methode zum Erweitern von Object.prototype. Dieser Code macht die Eigenschaft vor der Eigenschaftsaufzählung verborgen (für p in o)
Für die Browser, die defineProperty implementieren , können Sie die uniqueId-Eigenschaft wie folgt implementieren:
Weitere Informationen finden Sie unter https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty
quelle
Eigentlich müssen Sie den
object
Prototyp nicht ändern und dort eine Funktion hinzufügen. Das Folgende sollte für Ihren Zweck gut funktionieren.quelle
object
Hacks. Sie müssen es nur ausführen, wenn Sie möchten, dass das Objekt des OP übereinstimmt, und es bleibt den Rest der Zeit aus dem Weg.Für Browser, die die
Object.defineProperty()
Methode implementieren , generiert der folgende Code eine Funktion, die Sie an jedes Objekt binden können, das Sie besitzen.Dieser Ansatz hat den Vorteil, dass er nicht erweitert wird
Object.prototype
.Der Code überprüft, ob das angegebene Objekt eine
__objectID__
Eigenschaft hat, und definiert es als versteckte (nicht aufzählbare) schreibgeschützte Eigenschaft, wenn nicht.Es ist also sicher gegen jeden Versuch, die schreibgeschützte
obj.__objectID__
Eigenschaft nach ihrer Definition zu ändern oder neu zu definieren, und löst durchweg einen netten Fehler aus, anstatt stillschweigend fehlzuschlagen.Im extremen Fall, in dem bereits
__objectID__
ein anderer Code für ein bestimmtes Objekt definiert worden wäre, würde dieser Wert einfach zurückgegeben.quelle
jQuery-Code verwendet eine eigene
data()
Methode als solche ID.Bei der Backstage-Methode
data
wird ein ganz besonderes Feld in der soobject
genannten"jQuery" + now()
put there next-ID eines Streams eindeutiger IDs wie erstelltIch würde vorschlagen, dass Sie dieselbe Methode verwenden, mit der John Resig offensichtlich alles über JavaScript weiß, und seine Methode basiert auf all diesem Wissen.
quelle
data
Methode von jQuery weist Fehler auf. Siehe zum Beispiel stackoverflow.com/questions/1915341/… . Außerdem weiß John Resig keineswegs alles, was es über JavaScript zu wissen gibt, und zu glauben, dass er Ihnen als JavaScript-Entwickler nicht hilft.Typoskript-Version von @justin answer, ES6-kompatibel, mit Symbolen, um Schlüsselkollisionen zu verhindern, und der Einfachheit halber in die globale Object.id eingefügt. Kopieren Sie einfach den folgenden Code, fügen Sie ihn ein oder fügen Sie ihn in eine ObjecId.ts-Datei ein, die Sie importieren möchten.
Anwendungsbeispiel:
quelle
Ich habe Code wie diesen verwendet, der dazu führt, dass Objekte mit eindeutigen Zeichenfolgen stringifiziert werden:
Die
__proto__
Bits sollen verhindern, dass der__id__
Getter im Objekt auftaucht. Dies wurde nur in Firefox getestet.quelle
__defineGetter__
nicht dem Standard entspricht.Ungeachtet der Empfehlung, Object.prototype nicht zu ändern, kann dies in einem begrenzten Umfang dennoch zum Testen sehr nützlich sein. Der Autor der akzeptierten Antwort hat sie geändert, stellt sie aber immer noch ein
Object.id
, was für mich keinen Sinn ergibt. Hier ist ein Ausschnitt, der den Job macht:quelle
Ich hatte das gleiche Problem und hier ist die Lösung, die ich mit ES6 implementiert habe
quelle
Um zwei Objekte zu vergleichen, besteht die einfachste Möglichkeit darin, einem der Objekte zu dem Zeitpunkt, zu dem Sie die Objekte vergleichen müssen, eine eindeutige Eigenschaft hinzuzufügen, zu überprüfen, ob die Eigenschaft in dem anderen vorhanden ist, und sie dann erneut zu entfernen. Dies spart übergeordnete Prototypen.
quelle