Wie erhält man JavaScript-Objektreferenzen oder Referenzzähler?
Wie man Referenzzähler für ein Objekt
- Ist es möglich zu bestimmen, ob ein javascript-Objekt hat mehrere Verweise?
- Oder ob es Referenzen außer die, die ich auf es zu mit?
- Oder auch nur, um die reference count selbst?
- Finde ich diese Informationen von javascript selbst, oder werde ich brauchen, um zu verfolgen, meine eigene Referenz Zähler.
Offensichtlich, es muss mindestens eine Referenz auf es für meinen code auf das Objekt zugreifen. Aber was ich wissen möchte ist, ob es irgendwelche anderen Hinweise haben, oder wenn mein code ist der einzige Ort auf diese zugegriffen wird. Ich möchte in der Lage sein, um das Objekt zu löschen, wenn nichts anderes, es verweist.
Wenn Sie die Antwort wissen, gibt es keine Notwendigkeit, um Lesen Sie den rest dieser Frage. Unten ist nur ein Beispiel, um die Dinge klarer.
Use-Case -
In meiner Anwendung habe ich eine Repository
Objekt-Instanz namens contacts
enthält ein array von ALLE meine Kontakte. Es gibt auch mehrere Collection
Objekt-Instanzen, wie friends
Sammlung und eine coworkers
Sammlung. Jede Sammlung enthält ein array mit einem anderen Satz von Gegenständen aus dem contacts
Repository
.
Beispielcode
Machen dieses Konzept zu konkretisieren, betrachten Sie den code unten. Jede Instanz des Repository
- Objekt enthält eine Liste aller Objekte eines bestimmten Typs. Haben Sie vielleicht ein repository von Kontakte und ein separates repository von Veranstaltungen. Um es einfach zu halten, können Sie nur erhalten, hinzufügen und entfernen von Elementen, und viele über den Konstruktor.
var Repository = function(items) {
this.items = items || [];
}
Repository.prototype.get = function(id) {
for (var i=0,len=this.items.length; i<len; i++) {
if (items[i].id === id) {
return this.items[i];
}
}
}
Repository.prototype.add = function(item) {
if (toString.call(item) === "[object Array]") {
this.items.concat(item);
}
else {
this.items.push(item);
}
}
Repository.prototype.remove = function(id) {
for (var i=0,len=this.items.length; i<len; i++) {
if (items[i].id === id) {
this.removeIndex(i);
}
}
}
Repository.prototype.removeIndex = function(index) {
if (items[index]) {
if (/* items[i] has more than 1 reference to it */) {
//Only remove item from repository if nothing else references it
this.items.splice(index,1);
return;
}
}
}
Beachten Sie die Zeile in remove
mit dem Kommentar. Ich nur wollen, entfernen Sie das Element aus meiner master-repository-Objekte, wenn keine anderen Objekte haben eine Referenz auf das Element. Hier ist Collection
:
var Collection = function(repo,items) {
this.repo = repo;
this.items = items || [];
}
Collection.prototype.remove = function(id) {
for (var i=0,len=this.items.length; i<len; i++) {
if (items[i].id === id) {
//Remove object from this collection
this.items.splice(i,1);
//Tell repo to remove it (only if no other references to it)
repo.removeIndxe(i);
return;
}
}
}
Dann dieser code verwendet Repository
und Collection
:
var contactRepo = new Repository([
{id: 1, name: "Joe"},
{id: 2, name: "Jane"},
{id: 3, name: "Tom"},
{id: 4, name: "Jack"},
{id: 5, name: "Sue"}
]);
var friends = new Collection(
contactRepo,
[
contactRepo.get(2),
contactRepo.get(4)
]
);
var coworkers = new Collection(
contactRepo,
[
contactRepo.get(1),
contactRepo.get(2),
contactRepo.get(5)
]
);
contactRepo.items; //contains item ids 1, 2, 3, 4, 5
friends.items; //contains item ids 2, 4
coworkers.items; //contains item ids 1, 2, 5
coworkers.remove(2);
contactRepo.items; //contains item ids 1, 2, 3, 4, 5
friends.items; //contains item ids 2, 4
coworkers.items; //contains item ids 1, 5
friends.remove(4);
contactRepo.items; //contains item ids 1, 2, 3, 5
friends.items; //contains item ids 2
coworkers.items; //contains item ids 1, 5
Bemerken, wie coworkers.remove(2)
nicht entfernen, id-2, von contactRepo? Dies ist, weil es noch referenziert von friends.items
. Allerdings friends.remove(4)
Ursachen id 4 entfernt werden contactRepo
weil keine andere Sammlung ist darauf zu verweisen.
Zusammenfassung
Oben ist, was ich tun will. Ich bin sicher, es gibt Möglichkeiten, ich kann dies tun, indem Sie die Verfolgung von meinen eigenen Referenz-Zähler und so. Aber wenn es einen Weg gibt, es zu tun, mit javascript, built-in reference management, würde ich gerne hören, wie man es benutzt.
InformationsquelleAutor der Frage Tauren | 2010-05-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, Nein, Nein, Nein; und ja, wenn Sie wirklich brauchen, um count Referenzen Sie haben, um es manuell tun. JS hat keine Schnittstelle zu dieser, GC, oder schwache Referenzen.
Während Sie könnte implementieren einer manuellen Referenz-gezählt Objekt-Liste, es ist fraglich, ob all die zusätzlichen Gemeinkosten (in Bezug auf Leistung, aber wichtiger ist die Komplexität des Codes) ist es Wert.
In deinem Beispiel-code es scheint einfacher, zu vergessen, die
Repository
mit einem einfachenArray
für Ihre Listen, und lassen Sie standard-garbage collection kümmert, fallen unbenutzt Menschen. Wenn Sie benötigt, um eine Liste aller Leute im Einsatz, würde nurconcat
diefriends
undcoworkers
Listen (Sortieren und/uniquify, wenn Sie Sie benötigt).InformationsquelleAutor der Antwort bobince
Sie vielleicht interessieren, schauen Sie in reduce-Funktionen " und "array".Funktionen auf der Karte. Karte könnte verwendet werden, um zu helfen, herauszufinden, wo Ihre Sammlungen überschneiden, oder wenn es eine Kreuzung an alle. Ein Benutzer definiert senken-Funktion kann verwendet werden, wie eine Zusammenführung (ein bisschen wie das überschreiben der Additionsoperator, so dass Sie anwenden können, Betrieb, um-Objekte-oder merge-alle Sammlungen, die auf "- id" wenn Sie das so definieren Sie Ihre Funktion reduzieren - dann weisen Sie das Ergebnis Ihrer master-Referenz-array, empfehle ich halten ein Schatten array enthält alle root-Objekt/- Werte in Fall, dass Sie möchten, um zurück-oder so). Hinweis: man muss vorsichtig sein, der Prototyp Ketten, wenn die Reduzierung ein Objekt oder ein array. Die map-Funktion wird sehr hilfreich sein in diesem Fall.
Ich würde vorschlagen, nicht entfernen Sie das Objekt oder Datensatz, der in Ihrem Repository wie Sie möchten, verweisen Sie es später erneut. Mein Ansatz wäre eine ShadowRepository reflektieren würden alle Datensätze/Objekte, die über mindestens einen "Referenz". Von deiner Beschreibung und den code hier vorgestellt, es scheint, Sie sind in der Initialisierung alle Daten und speichert Referenz zu 1,2,4,5 wie wird in Ihrem code.
Aus der Initialisierung des Repository und den Sammlungen, was Sie Fragen: "Element Entfernen aus dem repository, wenn es keine Hinweise", Punkt 3 würde müssen entfernt werden sofort. Sie können jedoch verfolgen Sie die Verweise in ein paar verschiedene Möglichkeiten.
Habe ich als mit dem Objekt.beachten Sie für eine ähnliche situation. Jedoch, Objekt.beobachten, funktioniert nicht in allen Browsern. Ich habe vor kurzem wandte sich an WatchJS
Arbeite ich an dem Verständnis der code hinter Watch.JS zu erlauben, eine Liste von Beobachtern auf ein Objekt dynamisch erstellt werden dies ermöglichen würde auch ein Element entfernen, wird nicht mehr beobachtet, aber ich schlage vor, entfernen Sie die Referenz am point-of-access - Was ich meine ist eine variable, die Aktien der unmittelbaren lexikalischen scope mit einem Objekt, gegeben hat, einen einzigen Bezugspunkt, um es Geschwister können entfernt werden, so dass es nicht mehr zugänglich außerhalb des Objekts, das Sie damals ausgesetzt hatte, die Aufnahme/Element/Eigenschaft/Objekt der Geschwister. Mit dem Verweis, dass alle anderen Referenzen, davon abhing, entfernt, Zugriff auf die zugrunde liegenden Daten gestoppt wird. Ich bin generieren eindeutige id für den Ursprung verweisen, um ein versehentliches wiederverwenden das gleiche.
Vielen Dank für Ihre Frage und die Struktur, die Sie verwenden, es hat mir geholfen zu überlegen, eines meiner eigenen, spezifischen Fällen, in denen ich war die Generierung eindeutig identifiziert Verweise auf lexikalische Geschwister diese eindeutige ids, die gehalten wurden, auf der EINEN Gegenstand, Umfang hatte, Nach dem Lesen hier habe ich neu überdacht und entschieden zu entlarven, nur eine Referenz zu weisen, dass der Verweis auf einen Variablen-Namen, wo immer es gebraucht wird, wie in erstellen von einem Wächter oder Beobachter oder eine andere Sammlung.
InformationsquelleAutor der Antwort corpus_khu