Как получить счетчик ссылок для объекта
- Можно ли определить, имеет ли объект javascript несколько ссылок на него?
- Или, если у него есть ссылки помимо той, к которой я обращаюсь с ?
- Или даже просто получить счетчик ссылок сам по себе?
- Могу ли я найти эту информацию из самого javascript или мне нужно будет отслеживать мои собственные счетчики ссылок.
Очевидно, что для моего кода доступа к объекту должна быть хотя бы одна ссылка на него. Но я хочу знать, есть ли какие-либо другие ссылки на него, или если мой код - единственное место, к которому он доступен. Я хотел бы иметь возможность удалить объект, если на него ничего не ссылается.
Если вы знаете ответ, нет необходимости читать остальную часть этого вопроса. Ниже приведен лишь пример, чтобы прояснить ситуацию.
Вариант использования
В моем приложении у меня есть Repository
экземпляр объекта с именем contacts
, который содержит массив ALL моих контактов. Существует также несколько экземпляров объекта Collection
, таких как коллекция friends
и коллекция coworkers
. Каждая коллекция содержит массив с различным набором элементов из contacts
Repository
.
Пример кода
Чтобы конкретизировать эту концепцию, рассмотрим код ниже. Каждый экземпляр объекта Repository
содержит список всех элементов определенного типа. Возможно, у вас есть хранилище Contacts и отдельное хранилище Events . Для простоты вы можете просто получать, добавлять и удалять элементы, а также добавлять многие с помощью конструктора.
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)
не удалил id 2 из contactRepo? Это потому, что на него все еще ссылаются из friends.items
. Однако friends.remove(4)
приводит к удалению идентификатора 4 из contactRepo
, поскольку ни одна другая коллекция не ссылается на него.
Резюме
Это то, что я хочу сделать. Я уверен, что есть способы, которыми я могу сделать это, отслеживая мои собственные счетчики ссылок и тому подобное. Но если есть способ сделать это, используя встроенное в Javascript управление ссылками, я хотел бы услышать о том, как его использовать.