2013-11-22 7 views
3

Хорошо, сначала я знаю, что объект не имеет ссылки на его контейнер, если явно не определено, поэтому я ищу работу здесь.Доступ к родительскому объекту

Возьмем следующий код (сильно упрощенным от моего случая использования для удобства чтения):

var cid = 0; 
var Command = function(c) { 
    this.id = cid += 1; 
    this.transient = false; 
    return this; 
} 

var sid = 0; 
var CommandSet = function() { 
    this.id = sid += 1; 
    this.commands = []; 
    this.transients = 0; 
    return this; 
} 

CommandSet.prototype.parent = null; 
CommandSet.prototype.recurse = function(callback) { 
    callback.call(this); 
    if (this.parent instanceof CommandSet) { 
     this.parent.recurse(callback); 
    } 
} 

CommandSet.prototype.createSubset = function() { 
    var set = new CommandSet(); 
    set.parent = this; 
    set.commands = this.commands; 
    set.transients = this.transients; 
    return set; 
} 


CommandSet.prototype.addCommand = function(c) { 
    if (c instanceof Command) { 
     this.commands.push(c); 
     if (c.transient) { 
      this.recurse(function() { 
       this.transients++; 
      }); 
     } 
    } 
    return this; 
} 

CommandSet.prototype.toggleTransient = function(c) { 
    if (c instanceof Command) { 
     c.transient = true; 
     this.recurse(function() { 
      this.transients++; 
     }); 
    } 
    return this; 
} 

Если я после этого сделайте следующее (http://jsfiddle.net/5KGd8/1/):

var s1 = new CommandSet(); 
var c1 = new Command(); 
var c2 = new Command(); 
s1.addCommand(c1).addCommand(c2); 

var s2 = s1.createSubset(); 
var s3 = s1.createSubset(); 
s2.toggleTransient(c1); 

console.log(s1); 
console.log(s2); 
console.log(s3); 

s1 теперь имеет 1 преходящее, s2 теперь имеет 1 переходный период, но s3 все еще не имеет ни одного, несмотря на то, что содержит ссылку на те же объекты Command.

Возможные решения:

  1. Я мог бы построить ссылку в каждую команду, которая хранит все наборы он расположен внутри и перебирать те, однако это собирается вызвать серьезные проблемы с памятью поскольку реальная природа моего приложения требует, чтобы подмножества могли быть собраны в мусор (пользователь будет создавать много из них анонимно часто, не осознавая этого), и это сохранит ссылку на них после их использования. Ссылка parent прекрасна, так как я хочу, чтобы родительский набор существовал до тех пор, пока у него есть выжившее подмножество.

  2. Я не мог явно заставить пользователя запустить функцию удаления на подмножества, когда он больше не нужен, который будет удалить все внутренние ссылки на него нет, но это усложняет вещи для их, и мне нравится то, чтобы работать автоматически. Природа моего приложения означает, что я хотел бы, чтобы пользователь создавал подмножества в моменты, когда они, возможно, даже не понимали, что они это сделали (через другие функции, которые создают и выполняют на подмножествах).

Может кто-нибудь подумать над тем, как решить эту проблему без проблем, описанных в моих двух решениях?

+0

Почему вы возвращаете это из функций, называемых конструкторами? –

+0

@BenjaminGruenbaum нет причина ... без причины. –

+0

Хорошо, просто для уточнения - вы хотели бы выяснить количество переходных процессов команды (не уверен, что это означает) на основе всех надмножеств, в которых он входит? –

ответ

1

Извините, но это не ответ, но я хочу, чтобы я понял проблему.

Команда CommandSet может иметь команды, когда вы изменяете свойство переходного процесса Command, вы хотели бы, чтобы CommandSet (s), которые содержат эту команду, имели обновленный счетчик переходных команд, которые он содержит.

Если история заканчивается здесь, вы можете просто получить команду Command, которая содержит команду Command и обновить ее контейнеры.

Это не сработает, потому что у вас будут созданные CommandSets в функции, и когда они выйдут из области видимости, они не будут собираться мусором, потому что в них содержатся ссылки, которые они содержат. Эти команды не выходят за рамки с помощью CommandSets, потому что они также содержатся в других (глобальных) командных наборах.

Повторное присвоение примитивного типа (переходные процессы) не назначает его в подмножестве или главном наборе, но что, если переходные процессы не были примитивными?

В конструкторе:

this.transients = {count:0}; 

В createSubset

set.transients = this.transients 

В toggleTransient

this.transients.count++; or -- 

Не важно, если вы возиться с переходными процессами в подмножестве или основного набора, до тех пор, вы используете toggleTransient, он изменит count для всех.

+0

Спасибо, у вас есть хорошая проблема. Хотя я упростил свою проблему в вопросе и забыл упомянуть, что подмножество может иметь различное количество переходных процессов для своего родительского набора (в моих реальных подмножествах для использования обычно содержатся только некоторые из их родительских команд). Проблема с передачей счетчика переходных процессов посредством ссылки на подмножества заключается в том, что они всегда будут иметь тот же показатель переходного процесса, что и родительский и наоборот. –

+0

@GeorgeReith Есть ли ограничение на срок действия CommandSets? Например, когда они не используются в течение определенного времени, вы можете с уверенностью сказать, что они истекли, и ссылки на их команды могут быть очищены? – HMR

+0

Боюсь, что нет. Пользователь полностью зависит от того, когда 'CommandSet' больше не актуальны, позволяя им выйти из сферы действия. Обратите внимание, что пользователь в этом случае является другим программистом; это часть библиотеки, которую я создаю. –

Смежные вопросы