如何在 JavaScript 和浏览器中处理循环引用
How is cyclic referencing handled in javascript and browsers?
我一直在探索各种 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 或其他东西)。
将失败的破坏者.js测试的完整要点:https://gist.github.com/2960549
浏览器不在乎。问题是您使用的工具无法通过对象图检查循环引用链。这些是完全合法的,至少如果你想要它们并期待它们,它们是合法的。
如果您考虑一个对象及其属性,以及通过这些属性直接或间接引用的对象,则该程序集将构成一个图形。 如果可以跟踪引用并回到您开始的地方,那么这意味着图形有一个循环。 语言允许循环绝对是一件好事。它是否适合给定的系统取决于相关代码。
因此,例如,一个递归函数遍历对象图而不检查它是否已经访问过某个对象,如果图是循环的,肯定会触发"太多递归"错误。
将只有两个对象相互引用(称为"循环引用")。
var a, b = {a: a={b: b}};
// a.b: pointer to b
// b.a: pointer to a
根本没有递归。如果您遇到too much recursion
或Maximum call stack size exceeded
错误,则需要有一个过于频繁调用的函数。例如,当您尝试克隆对象并在不关心循环引用的情况下递归属性时,可能会发生这种情况。您需要在代码中进一步查看,错误消息还应包含(很长的)调用堆栈。
- 如何使用jquery处理php循环通过元素
- Javascript在for循环中等待处理请求
- 在循环中附加事件处理程序时出现浏览器性能问题
- 如何处理javascript中的循环引用,类似于Excel提供迭代限制的方式
- Emberjs#每个循环不处理数组数据
- jQuery:如何在没有for循环的情况下将事件处理程序应用于$('#text'+'任意整数
- 在嵌套循环中处理 AJAX (Angularjs)
- RxJS:在循环中处理错误.js自定义驱动程序
- 在处理元素单击事件期间,在循环内部调用window.open()
- 将事件处理程序分配给for循环中的每个按钮
- 如何在 JavaScript 和浏览器中处理循环引用
- 处理循环变量的重复声明警告
- 添加HTML按钮以处理循环数组中的元素上的增量
- 使用nodejs异步回调处理循环
- 处理循环依赖
- 在单独的文件中考虑模型:如何处理循环/循环依赖关系
- 处理循环数组请求的错误
- 如何在AngularJS中处理循环中的if语句
- 以角度同步处理循环
- 如何在这样的javascript代码中处理循环复杂性