访问对象'的父级

Accessing an object's parent

本文关键字:对象 访问      更新时间:2023-09-26

好的,首先我知道一个对象没有引用它的容器,除非明确定义,所以我正在寻找解决方案。

以以下代码为例(为了可读性,从我的用例中进行了大量简化):

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. 我可以明确地强制用户在当不再需要它时,它会删除所有对它的内部引用,但这会使他们和我都喜欢自动工作。我的应用程序的性质意味着我希望用户在他们甚至没有意识到自己已经创建了子集的时候创建子集(通过创建和执行子集的其他功能)。

如果没有我的两个解决方案中描述的问题,有人能想出解决这个问题的方法吗?

对不起,这不是一个答案,但我想确保我理解这个问题。

命令集可以有命令,当您更改命令的瞬态属性时,您希望包含该命令的命令集具有其包含的瞬态命令的更新计数器。

如果故事到此结束,您可以简单地让Command维护命令所在的CommandSet列表,并更新其容器。

但是,这将不起作用,因为您将在函数中创建CommandSet,并且当这些CommandSet超出范围时,它们不会被垃圾收集,因为它们包含的命令将包含对它们的引用。这些命令不会超出CommandSet的作用域,因为它们也包含在其他(全局)CommandSet中。

重新分配基元类型(瞬变)不会在子集或主集中重新分配,但如果瞬变不是基元呢?

在构造函数中:

this.transients = {count:0};

在createSubset 中

set.transients = this.transients

在开关中瞬态

this.transients.count++; or --

无论你是在子集还是主集中摆弄瞬变,只要你使用toggleTransient,它就会改变所有的count