好的,首先我知道对象除非明确定义否则没有对其容器的引用,因此我正在寻找一个解决方法。
请看以下代码(为了易读性大幅简化了我的用例):
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
现在有一个瞬态,s2
现在也有一个瞬态,但是s3
仍然没有,尽管它包含对相同Command
对象的引用。
可能的解决方案:
我可以为每个命令构建一个引用,其中存储了所有包含它的集合,并遍历这些集合,但这将导致一些严重的内存问题,因为我的应用程序的真实性质要求子集可以被垃圾回收(用户通常会匿名创建许多子集而不知道),而这将在使用后保留对它们的引用。
parent
引用很好,因为我希望父集存在,只要它有一个存活的子集。我可以明确地强制用户在不再需要子集时运行删除函数,该函数将删除所有内部引用,但这会使事情变得复杂,并且我希望事情能够自动完成。我的应用程序的性质意味着用户可能在他们甚至没有意识到的情况下创建子集(通过创建和执行子集的其他功能)。
有人能想出一种解决这个问题的方法,而不会出现我两个解决方案中描述的问题吗?
commands
是一个数组,你只是复制了它的引用,但transients
是一个数字,它真正被复制了。 - jantimonCommand
对象上的一个布尔值。我希望所有包含Command
对象的集合都能够具有最新的计数,即包含一个瞬态值为true的Command
对象的数量。 - George Reiththis.commands
迭代返回正确的数量。如果不能,则可以将transient转换为返回transient命令的函数(不确定是否会极大地影响性能)。 - HMR