【问题标题】:How do I stop endless recursion when two objects reference each other? [closed]当两个对象相互引用时,如何停止无限递归? [关闭]
【发布时间】:2020-06-30 08:23:01
【问题描述】:

假设我想制作一个对象的深层副本。我使用递归来遍历它的属性。现在这些属性之一可以是一个对象。 例如:

Person A
  Name: "Fred"
  Best Friend: Person B

现在如果 B 是:

Person B
  Name: "Max"
  Best Friend: Person A

这将创建一个无休止的递归。我怎样才能避免这种无休止的循环?

【问题讨论】:

  • 代码在哪里?
  • 您可以查看来自Ramdapublicinternal——免责声明:我是作者)或lodashpublicinternal)的代码一些提示。诀窍是保留所有已克隆的地图并引用这些克隆而不是创建新的。

标签: javascript java recursion computer-science


【解决方案1】:

您可以使用与JSON.stringify 相同的逻辑来避免无限循环。

  1. 如果 state.[[Stack]] 包含值,则抛出 TypeError 异常,因为结构是循环的。

它保留一堆正在序列化的父对象。每次调用序列化新值的方法时,都会检查堆栈,看该值是否已经在序列化过程中,如果是,则抛出错误。

在您的示例中,如果您要制作“Person A”的副本,则在考虑如何复制“Best Friend”属性时,父堆栈将是 [Person A]。更深入地讲,当序列化 Person B 的“Best Friend”属性时,父堆栈将是 [Person A, Person B]。看到下一个要序列化的项目,Person B 的“Best Friend”值,Person A,已经在堆栈中,抛出一个错误。

【讨论】:

  • 理想情况下,您可能需要的不仅仅是祖先,而是对象图中的任何其他节点。第一次克隆节点时,您会跟踪结果,并且无论何时在图表中需要克隆已有的内容时,您都不会再次执行此操作,而是返回副本。因此,如果克隆了{foo: obj, bar: obj},您将得到{foo: obj2, bar: obj2},其中obj2obj 的单个克隆。祖先跟踪对于避免无限递归是必要的,但这种技术对于对象大小和行为相似性都是必要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多