如何获取对象的引用计数
- 是否可以确定一个 javascript 对象是否对其有多个引用?
- 或者它是否有引用除了我正在访问它的引用?
- 或者甚至只是获取引用计数本身?
- 我能否从 javascript 本身找到此信息,或者我是否需要跟踪我自己的引用计数器。
显然,对于我的代码访问该对象,必须至少有一个对它的引用。但我想知道的是是否有任何其他对它的引用,或者我的代码是否是唯一访问它的地方。如果没有其他对象引用它,我希望能够删除该对象。
如果您知道答案,则无需阅读此问题的其余部分。下面只是一个示例,目的是让事情更清楚。
用例
在我的应用程序中,我有一个名为 contacts
的 Repository
对象实例,其中包含我的ALL 联系人数组。还有多个 Collection
对象实例,例如 friends
集合和一个 coworkers
集合。每个集合都包含一个数组,其中包含来自 contacts
Repository
的不同项目集。
示例代码
为了使这个概念更具体,请考虑以下代码。 Repository
对象的每个实例都包含特定类型的所有项的列表。您可能有一个联系人 存储库和一个单独的事件 存储库。为简单起见,您只需获取、添加和删除项,并通过构造函数添加许多项。
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;
}
}
}
注意 remove
中带有注释的行。如果没有其他对象引用该项目,我只想从我的对象主存储库中删除该项目。这是集合
:
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;
}
}
}
然后此代码使用Repository
和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
请注意 coworkers.remove(2)
没有从 contactRepo 中删除 id 2?这是因为它仍然被 friends.items
引用。但是,friends.remove(4)
导致 id 4 从 contactRepo
中删除,因为没有其他集合引用它。
总结
以上是我想做的。我确信有一些方法可以通过跟踪我自己的引用计数器等来做到这一点。但是,如果有一种方法可以使用 javascript 的内置引用管理来做到这一点,我想听听如何使用它。
最佳答案
不,不,不,不;是的,如果你真的需要计算引用,你将不得不手动完成。 JS没有this、GC、weak references接口(interface)。
虽然您可以实现一个手动的引用计数对象列表,但值得怀疑的是所有额外的开销(在性能方面,但更重要的是代码复杂性)是否值得。
在您的示例代码中,忘记 Repository
似乎更简单,为您的列表使用普通的 Array
,并让标准垃圾收集负责丢弃未使用的人。如果您需要获取所有在用人员的列表,您只需concat
friends
和coworkers
列表(并对它们进行排序/唯一化)如果你需要的话)。
关于javascript - 如何获取 javascript 对象引用或引用计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2937120/