最佳答案
显然,必须至少有一个对它的引用,以便我的代码访问该对象。但我想知道的是,是否还有其他引用,或者我的代码是否是唯一访问它的地方。我希望能够删除对象,如果没有其他引用它。
如果你知道答案,就没有必要阅读这个问题的其余部分。下面只是一个例子,让事情变得更清楚。
在我的应用程序中,我有一个名为 contacts
的 Repository
对象实例,它包含一个 全部联系人数组。还有多个 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
中带有注释的行。只有在没有其他对象引用该项的情况下,我才希望从对象的主存储库中删除该项。这里是 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;
}
}
}
然后这段代码使用 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)
会导致从 contactRepo
中删除 id4,因为没有其他集合引用它。
以上就是我想做的。我相信我可以通过跟踪自己的参考计数器之类的方法来做到这一点。但是,如果有一种方法可以使用 javascript 的内置引用管理来实现这一点,我想听听如何使用它。