如何获取javascript对象引用或引用计数? [英] How to get javascript object references or reference count?

查看:166
本文介绍了如何获取javascript对象引用或引用计数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获取对象的引用计数




  • 是否可以确定javascript对象是否具有多个引用强>它?

  • 或者甚至只是为了获取引用计数本身?

  • 我可以从javascript本身找到这些信息,我需要跟踪自己的引用计数器。



显然,我的代码必须至少有一个引用来访问目的。但是我想知道的是,如果还有其他引用,或者我的代码是唯一被访问的地方。我希望能够删除该对象,如果没有别的引用它。



如果您知道答案,则无需阅读其余的内容 使用案例 >

在我的应用程序中,我有一个 Repository 对象实例,名为 contacts 其中包含所有我的联系人数组。还有多个集合对象实例,比如好友集合和同事集合。每个集合包含一个数组,其中包含来自 contacts Repository 的一组不同的项目。



示例代码



为了使这个概念更具体,请考虑下面的代码。 Repository 对象的每个实例都包含特定类型的所有项目的列表。您可能拥有联系人存储库和事件的单独存储库。为了简单起见,您可以通过构造函数获取,添加和删除项目,并添加许多项。

  var Repository =函数(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];


$ b 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);


$ b Repository.prototype.removeIndex = function(index){
if(items [index]){
if(/ * items [i]有超过1个引用它* /){
//只从项目库中删除项目,如果没有其他的参考它
this.items.splice(index,1);
return;





$ b

注意<$ code>删除与评论。如果没有其他对象具有对该项目的引用,我只想从我的主对象存储库中删除该项目。这里是集合

  var Collection = function(repo,items){ 
this.repo = repo;
this.items =物品|| [];
}
Collection.prototype.remove = function(id){
for(var i = 0,len = this.items.length; i< len; i ++){
if(items [i] .id === id){
//从这个集合中移除对象
this.items.splice(i,1);
//告诉repo将其删除(仅当没有其他引用时)
repo.removeIndxe(i);
return;





$ b然后这段代码使用 Repository 集合

  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 =新集合(
contactRepo,
[
contactRepo.get(2),
contactRepo.get(4)
]
);

var coworkers =新集合(
contactRepo,
[
contactRepo.get(1),
contactRepo.get(2),
contactRepo.get(5)
]
);

contactRepo.items; //包含项目标识1,2,3,4,5
friends.items; //包含项目id 2,4
coworkers.items; //包含项目ID 1,2,5

coworkers.remove(2);

contactRepo.items; //包含项目标识1,2,3,4,5
friends.items; //包含项目id 2,4
coworkers.items; //包含项目标识1,5

friends.remove(4);

contactRepo.items; //包含项目标识1,2,3,5
friends.items; //包含项目id 2
coworkers.items; //包含项目ID 1,5

注意 coworkers.remove(2 )没有从contactRepo中删除ID 2?这是因为它仍然是从 friends.items 引用的。但是, friends.remove(4)会导致id 4从 contactRepo 中被移除,因为没有其他集合被引用它。

总结



以上就是我想要做的。我确信我可以通过跟踪自己的参考计数器等来做到这一点。但是,如果有一种方法可以使用JavaScript的内置参考管理来实现,那么我想知道如何使用它。 解决方案

不,不,不,不;是的,如果你真的需要数引用,你将不得不手动。 JS没有这个接口,GC或者弱引用。



虽然你可以实现一个手工引用计数的对象列表,但是否值得怀疑所有额外的开销(在性能方面,但更重要的是代码复杂性)是值得的。



在您的示例代码中,忘记 Repository ,为你的清单使用一个普通的 Array ,并让标准的垃圾回收处理掉不用的人。如果你需要得到所有使用者的清单,你只需 concat 好友同事列出(并根据需要对其进行排序/分类)。


How to get reference count for an object

  • Is it possible to determine if a javascript object has multiple references to it?
  • Or if it has references besides the one I'm accessing it with?
  • Or even just to get the reference count itself?
  • Can I find this information from javascript itself, or will I need to keep track of my own reference counters.

Obviously, there must be at least one reference to it for my code access the object. But what I want to know is if there are any other references to it, or if my code is the only place it is accessed. I'd like to be able to delete the object if nothing else is referencing it.

If you know the answer, there is no need to read the rest of this question. Below is just an example to make things more clear.


Use Case

In my application, I have a Repository object instance called contacts that contains an array of ALL my contacts. There are also multiple Collection object instances, such as friends collection and a coworkers collection. Each collection contains an array with a different set of items from the contacts Repository.

Sample Code

To make this concept more concrete, consider the code below. Each instance of the Repository object contains a list of all items of a particular type. You might have a repository of Contacts and a separate repository of Events. To keep it simple, you can just get, add, and remove items, and add many via the constructor.

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

Note the line in remove with the comment. I only want to remove the item from my master repository of objects if no other objects have a reference to the item. Here's 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;
    }
  }
}

And then this code uses Repository and 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

Notice how coworkers.remove(2) didn't remove id 2 from contactRepo? This is because it was still referenced from friends.items. However, friends.remove(4) causes id 4 to be removed from contactRepo, because no other collection is referring to it.

Summary

The above is what I want to do. I'm sure there are ways I can do this by keeping track of my own reference counters and such. But if there is a way to do it using javascript's built-in reference management, I'd like to hear about how to use it.

解决方案

No, no, no, no; and yes, if you really need to count references you will have to do it manually. JS has no interface to this, GC, or weak references.

Whilst you could implement a manual reference-counted object list, it's questionable whether all the extra overhead (in performance terms but more importantly code complexity) is worth it.

In your example code it would seem simpler to forget the Repository, use a plain Array for your lists, and let standard garbage collection take care of dropping unused people. If you needed to get a list of all people in use, you'd just concat the friends and coworkers lists (and sort/uniquify them if you needed to).

这篇关于如何获取javascript对象引用或引用计数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆