56 votes

Comment obtenir des références d'objets javascript ou un décompte de références?

Comment obtenir le nombre de références d'un objet

  • Est-il possible de déterminer si un objet javascript a de multiples références à elle?
  • Ou si il a des références en plus de celui que je suis en accédant avec?
  • Ou même juste pour obtenir le compte de référence lui-même?
  • Puis-je trouver cette information à partir de javascript lui-même, ou ai-je besoin de garder une trace de mes propres compteurs de référence.

De toute évidence, il doit y avoir au moins une référence pour mon code d'accès à l'objet. Mais ce que je veux savoir c'est si il y a d'autres références à celui-ci, ou si mon code est le seul endroit où il est accessible. Je voudrais être en mesure de supprimer l'objet, si rien d'autre n'est référençant.

Si vous connaissez la réponse, il n'y a pas besoin de lire le reste de cette question. Ci-dessous est juste un exemple pour rendre les choses plus claires.


Cas D'Utilisation

Dans mon application, j'ai un Repository instance de l'objet appelé contacts qui contient un tableau de TOUS mes contacts. Il existe également plusieurs Collection des instances de l'objet, comme friends de la collection et un coworkers de la collecte. Chaque collection contient un tableau avec un autre ensemble d'éléments de l' contacts Repository.

Exemple De Code

Afin de rendre ce concept plus concret, considérons le code ci-dessous. Chaque instance de l' Repository objet contient une liste de tous les éléments d'un type particulier. Vous pouvez disposer d'un référentiel de Contacts et d'un autre référentiel des Événements. Pour faire simple, vous pouvez juste obtenir, d'ajouter et de supprimer des éléments, et d'ajouter de nombreux via le constructeur.

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;
    }
  }
}  

Remarque la ligne en remove avec le commentaire. Je ne veux supprimer l'élément de mon maître dépôt d'objets si pas d'autres objets ont une référence à l'élément. Voici 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;
    }
  }
}

Et puis, ce code utilise Repository et 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

Remarquez comment coworkers.remove(2) ne pas supprimer l'id 2 de contactRepo? C'est parce qu'il était encore référencé d' friends.items. Toutefois, friends.remove(4) causes id 4 pour être retiré de la contactRepo, car aucune autre collection est en se référant à elle.

Résumé

Le ci-dessus est ce que je veux faire. Je suis sûr qu'il ya des façons que je peux le faire en gardant la trace de mes propres compteurs de référence et d'exemple. Mais si il y a un moyen de le faire à l'aide de javascript intégré de gestion de références, j'aimerais vous entendre sur la façon de l'utiliser.

18voto

bobince Points 270740

Non, non, non, non; et oui, si vous avez vraiment besoin de compter les références que vous devrez le faire manuellement. JS n'a pas d'interface pour cela, GC, ou de la faiblesse des références.

Alors que vous pourriez mettre en œuvre un manuel de référence-compté objet de la liste, il est douteux que tous les frais généraux supplémentaires (en termes de performances, mais plus important encore, la complexité du code) en vaut la peine.

Dans votre exemple de code, il semblerait plus simple d'oublier l' Repository, utilisez un simple Array pour vos listes, et laissez-standard de collecte des ordures prendre soin de déposer inutilisés personnes. Si vous avez besoin pour obtenir une liste de toutes les personnes en cours d'utilisation, vous devriez juste concat le friends et coworkers listes (et de tri/uniquify si vous avez besoin d').

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X