0

我想为我的 javascript 对象创建一个类似 DSL 的构建器,但我不确定垃圾收集器(创建的对象)是否删除了 DSL-Builder 对象。这是代码:

function Section() {...}

Section.DSL = function() {
  var section = new Section();

  return {
    title: function(s) { section.title = s; },         /* Just for example */
    content: function(s) { section.content = s; },     /* Logic has been removed */
    section: section
  }
}

function section(builderFn) {
  var dsl = new Section.DSL();
  fn.call(dsl, dsl);

  return dsl.section;
}

/* Somewhere in the code */
var mySection = section(function(s) { 
  s.title('Hello, my section');
  s.content('We can put it in later');
});

/* I want my DSL object created internally by section method 
   to be removed by garbage collector */

我将仅使用 DSL 来初始化 Section 的新实例并使用方便的方法填充其值。我希望处理我的 DSL 对象,但我不确定它是否会根据我对其成员之一的进一步使用。

也许我应该创建一个“dispose”方法,它将 dsl.section 设置为 null 或使用“delete dsl.section”将其删除?之后,我的部分将与 DSL 断开连接,垃圾收集器将成功删除它,我通过新的引用“mySection”继续使用它。

还有一个想法:

有可能将 DSL 用作单例。在这种情况下,我必须在“section”方法中创建一个新的 Section 对象,然后在调用构建器函数之前将其分配给 DSL 对象(这将是一个单例)。这是一个很好的解决方案吗?示例如下:

Section.DSL = {
  construct: function(section) {
    this.section = section;
    return this;
  }

  /* Builder methods */
}

function section(builderFn) {
  var section = new Section();

  /*  Imagine that DSL is just an object with a few functions 
      and construct just set its section variable and returns this
   */
  var dsl = Section.DSL(section); **/
  fn.call(dsl, dsl);

  return section;
}
4

1 回答 1

0

GC关心对象可达性。无论如何,请考虑以下示例:

function f (s) {
  // The variable "s" is a reachability root for the given scope;
  // any object that it names is guaranteed to be reachable
  // as long as the closure(s) below are reachable.
  return {
     getIt: function () { return s }
     setIt: function (_s) { s = _s }
  }
}

示例案例 1。

g = f({my: "Object"})
// Closures are no longer strongly reachable, and thus the object
// can be reclaimed.
// (Also note there are no other strong references to the object!)
g = null
// Told yah, so, oops exception!
g.getIt()

示例案例 2。

g = f({my: "Object"})
// The variable "s" bound by the closures has been re-assigned and
// thus no longer strongly references the original object;
// the original object is thus eligible for reclamation.
// (Note no other strong references!)
g.setIt(null)
// But of course we just have null now .. oops!
g.getIt().my

示例案例 3。

o = {my: "Object"}
g = f(o)
g.setIt(null)
// ..but the object is NOT eligible for reclamation because it is
// strongly reachable through "o" (which is a reachability root
// in this scope).
alert(o)

现在,唯一真正感兴趣的案例(我在评论中没有提及)是:

function f2(s) {
   var hash_of_s = hash(s)
   // The variable "s" is not accessed from any closure
   return {
      getHash: function () { return hash_of_s }
   }
}
g = f2(/* some LARGE object currently only reachable here */)
// Is the object referenced by "s" reclaimable here?
alert(g.getHash())

在这种情况下,假设闭包是强可达的,“s”是否保持初始对象的可达性?

一个实现可以在技术上决定“s”不能保持可达性——但我知道 Node.js 是如何处理它的。

于 2013-01-29T19:23:32.877 回答