繁体   English   中英

为什么要递归并导致无限循环?

[英]Why is this recursive and causing an infinite loop?

我正在扩展Backbone.View以支持子视图,并且我有一个addSubview方法,该方法仅将Backbone视图添加到哈希中。 很简单。 我现在正试图做到这一点,以便每当您destroy视图时,它都会破坏所有子视图。 我以为这也很容易,但是我的方法陷入了无限循环:

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视图,第二次在第一个子视图(右)上调用了它,第三次-∞仍然继续调用了第一个子视图。 逐步进行操作:

  1. 打调试器
  2. 到达this._subviews[v].destroy(); 行和v ==第一个子视图
  3. 跳回到顶级调试器。

就这样。 并且它会永远重复。 有什么想法或建议吗?

演示: http//jsbin.com/iyApuga/1/edit

这里发生的是名为_subviewsobject存储在Foo.View的原型中(Backbone的extend方法正在执行此操作),因此被Foo.View所有实例共享。 这是设置的位置:

Foo.View = Backbone.View.extend({
    _subviews: {},  // right here

这会导致问题,因为在添加第一this._subviews视图时,它会添加到this._subviews 因为_subviews对象由View的每个实例共享,所以当您将子视图添加到子视图时,所有其他视图都认为View是其自身的子视图。

具体来说,这里发生的是,当您调用.destroy() ,在所有子视图上调用destroy()循环的顶部,意外地再次在相同的精确View上调用了destroy() 直到循环几行后, _subviews变量才会被清除:

// Instead of calling `delete` on every view we wipe everything out after
// we're done destroying all the views
this._subviews = {};

因此,它变得无限,因为它要遍历同一_subviews列表,并卡在第一个从未被删除的第一个_subviews上。

为了使世界开心, _subviews对象应该是每个View的实例变量,而不是View原型上的实例变量。 为此,您应该在每个新的View上分配一个新的View

  initialize: function () {
    this._subviews = {};
  }

问题是_subviews在父Foo Foo实例之间共享 解决方法是为每个实例初始化_subviews

initialize: function () {
    this._subviews = {};
}

当尝试以面向类的方式使用Javascript时,这是一个非常常见的陷阱。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM