好的,首先我知道一个对象没有引用它的容器,除非明确定义,所以我正在寻找一个解决方法。
采用以下代码(从我的用例中大大简化了可读性):
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
个对象的引用。
可能的解决方案:
我可以为每个存储所有内容的命令构建一个引用
设置它位于内部并迭代这些,但这是
将导致一些严重的记忆问题成为我的真实本质
应用程序要求可以对子集进行垃圾回收(用户
他们会在没有意识到的情况下匿名制造很多这样的东西,这将保留一个
使用后参考它们。 parent
引用很好,因为我希望父集合存在,只要它有一个幸存的子集。
我可以明确强制用户在a上运行删除功能 不再需要的子集会删除对它的所有内部引用,但这会使事情复杂化 他们和我喜欢自动工作的东西。我的应用程序的性质意味着我希望用户在他们甚至没有意识到他们已经这样做的时候创建子集(通过在子集上创建和执行的其他功能)。
如果没有我的两个解决方案中描述的问题,有没有人能想出解决这个问题的方法?
答案 0 :(得分:1)
对不起,这不是答案,但我想确保我理解这个问题。
CommandSet可以有命令,当你更改Command的transient属性时,你希望包含该Command的CommandSet有一个更新的瞬态计数器包含它包含的命令。
如果故事在这里结束,你可以简单地让Command维护Command所在的CommandSet列表并更新它的容器。
但是这不起作用,因为您将在函数中创建CommandSets,当这些命令超出范围时,它们将不会被垃圾收集,因为它们包含的命令将包含对它们的引用。这些命令不会超出CommandSets的范围,因为它们也包含在其他(全局)CommandSets中。
重新分配基本类型(瞬态)不会在子集或主集中重新分配,但如果瞬态不是原语会怎样?
在构造函数中:
this.transients = {count:0};
在createSubset
中set.transients = this.transients
在toggleTransient
中this.transients.count++; or --
无论你是否在子集或主集中调整瞬态,只要你使用toggleTransient,它就会为所有人改变count
。