【发布时间】:2012-06-23 00:11:27
【问题描述】:
我一直在探索各种 MV* 框架中的模式,今天注意到一个奇怪的模式,这似乎会导致一些问题
模型原型。有一个属性collections: []
集合原型。有一个属性models: []
当一个集合获得一个新模型时,它被推入collection.models,但模型本身也被修饰以知道它是其成员的集合——即集合实例被推入model.collections。
所以model.collections[0] 是一个集合,其中包含.models[0] 是具有集合属性的模型......等等。
最基本的:
var A = function() {
this.collections = [];
},
B = function() {
this.models = [];
this.add = function(what) {
what.collections.push(this);
this.models.push(what)
};
};
var model = new A();
var collection = new B();
collection.add(model);
这是有罪的一方:https://github.com/lyonbros/composer.js/blob/master/composer.js#L310-313,然后进一步向下推入模型:https://github.com/lyonbros/composer.js/blob/master/composer.js#L781-784
我想会有一定程度的懒惰评估——在需要之前不会使用东西。该代码 - 就其自身而言 - 有效。
但我也在通过 buster.js 编写测试,我注意到所有依赖于 sinon.spy() 的测试都产生了 InternalError: too much recursion (FF) 或 RangeError: Maximum call stack size exceeded(Chrome)。捕获的 FF 甚至没有响应地崩溃,这是我以前从未遇到过的 buster 测试驱动程序 - 它甚至在我的午休时间使用了 3.5gb 的内存。
经过大量调试后,我解开了参考存储,突然间,一切又恢复正常了。诚然,删除spy() 断言也有效,但这不是重点。
所以,问题是 - 有这样的代码,是否可以接受,浏览器将如何解释它,瓶颈是什么以及如何使用指向它们所属集合的指针来装饰模型(可能是集合控制器和收集 uid 之类的东西)。
将失败的 buster.js 测试的完整要点:https://gist.github.com/2960549
【问题讨论】:
-
这不是真正的“递归”。问题是循环引用。
-
更改标题以反映这一点
标签: javascript recursion buster.js