Javascript 为什么这是递归的,并导致无限循环?
我正在扩展Backbone.View以支持子视图,我有一个Javascript 为什么这是递归的,并导致无限循环?,javascript,backbone.js,recursion,Javascript,Backbone.js,Recursion,我正在扩展Backbone.View以支持子视图,我有一个addSubview方法,它只是将主干视图添加到散列中。很简单。我现在正试图使它成为这样,每当你销毁一个视图时,它就会销毁所有的子视图。我认为这也很容易,但我的方法是无限循环的: destroy: function () { debugger; // Call destroy on all subviews. If the subviews have subviews they'll // be destroyed as we
addSubview
方法,它只是将主干视图添加到散列中。很简单。我现在正试图使它成为这样,每当你销毁一个视图时,它就会销毁所有的子视图。我认为这也很容易,但我的方法是无限循环的:
destroy: function () {
debugger;
// Call destroy on all subviews. If the subviews have subviews they'll
// be destroyed as well
for (var v in this._subviews) {
this._subviews[v].destroy();
}
// Instead of calling `delete` on every view we wipe everything out after
// we're done destroying all the views
this._subviews = {};
// Finally, since all the subviews are destroyed it's safe to destroy
// this view
this.remove();
},
发生的情况是,调试器第一次被调用,this
是视图destroy
被调用(右),第二次在第一个子视图(右)上被调用,第三次-∞ 它仍然不断调用第一个子视图。一步一步地玩它:
this.\u子视图[v].destroy()代码>行和v
==第一个子视图
演示:问题在于父
Foo
和子Foo
实例之间共享\u子视图
:
initialize: function () {
this._subviews = {};
}
当试图以面向类的方式使用Javascript时,这是一个非常常见的问题。问题是
\u子视图在父Foo
和子Foo
实例之间共享。修复方法是为每个实例初始化\u子视图
:
initialize: function () {
this._subviews = {};
}
当试图以面向类的方式使用Javascript时,这是一个非常常见的问题。这里发生的事情是,名为\u子视图的对象存储在Foo.View
的原型上(主干的extend
方法就是这样做的)并因此被Foo.View
的所有实例共享。这里是设置的位置:
Foo.View = Backbone.View.extend({
_subviews: {}, // right here
这会导致一个问题,因为当您添加第一个子视图时,它会被添加到该子视图中。由于\u子视图
对象由视图
的每个实例共享,因此当您将子视图添加到子视图时,所有其他视图都认为视图
是它们自己的子视图
具体来说,这里发生的情况是,当您调用.destroy()
时,在所有子视图上调用destroy()
的循环的顶部,会再次意外地调用同一精确视图上的destroy()
。\u子视图
变量直到循环后的几行才被清除:
// Instead of calling `delete` on every view we wipe everything out after
// we're done destroying all the views
this._subviews = {};
因此,它变得无限,因为它在相同的\u子视图列表上反复迭代,停留在第一个似乎从未完全删除的视图上
为了让世界高兴,子视图对象应该是每个视图的实例变量,而不是原型视图上的实例变量。为此,您应该在每个新的视图上分配一个新的:
initialize: function () {
this._subviews = {};
}
这里发生的事情是,名为\u子视图的对象被存储在Foo.View
的原型上(主干的extend
方法就是这样做的),因此被Foo.View
的所有实例共享。这里是设置的位置:
Foo.View = Backbone.View.extend({
_subviews: {}, // right here
这会导致一个问题,因为当您添加第一个子视图时,它会被添加到该子视图中。由于\u子视图
对象由视图
的每个实例共享,因此当您将子视图添加到子视图时,所有其他视图都认为视图
是它们自己的子视图
具体来说,这里发生的情况是,当您调用.destroy()
时,在所有子视图上调用destroy()
的循环的顶部,会再次意外地调用同一精确视图上的destroy()
。\u子视图
变量直到循环后的几行才被清除:
// Instead of calling `delete` on every view we wipe everything out after
// we're done destroying all the views
this._subviews = {};
因此,它变得无限,因为它在相同的\u子视图列表上反复迭代,停留在第一个似乎从未完全删除的视图上
为了让世界高兴,子视图对象应该是每个视图的实例变量,而不是原型视图上的实例变量。为此,您应该在每个新的视图上分配一个新的:
initialize: function () {
this._subviews = {};
}
你能随便做一把小提琴吗?@thefourtheye在这儿你能随便做一把小提琴吗?@thefourtheye在这儿你能: