8

如果我有一个 JavaScript 构造函数,并且我在它的原型上设置了一个 destroy 方法。是否可以从 destroy 方法中删除(或至少取消设置)实例?这是我正在尝试做的一个例子。

Klass.prototype = {
  init: function() {
    // do stuff
  },
  destroy: function() {
    // delete the instance    
  }
};

k = new Klass
k.destroy()
console.log(k) // I want this to be undefined

我知道我不能简单地this = undefined使用 destroy 方法,但我认为我可以通过使用像这样的超时来解决这个问题:

destroy: function() {
  var self = this;
  setTimeout( function() {
    self = undefined
  }, 0)  
}

我认为超时函数可以通过闭包访问实例self(确实如此),但这似乎不起作用。如果我console.log(self)从该函数内部显示为undefined,但k在全局范围内仍然是Klass.

有谁知道如何使这项工作?

4

4 回答 4

4

k是指向 的实例的引用Klass。当您destroy作为内部方法调用时Klassthis函数会绑定到您调用destroy方法的对象。它现在是对该实例的另一个引用Klass。您在self那个小闭包中关闭的 是对该实例的另一个引用。当您将其设置为undefined您清除该引用时,而不是它背后的实例。你不能真的destroy那个实例本身。您可以忘记它(将所有引用设置为undefined,您将不会再找到它),但这是您所能做到的。

就是说,告诉我们您想用这个完成什么,我们很乐意帮助您找到解决方案。

于 2012-05-31T00:45:14.183 回答
2

虽然删除自己的对象实例是可能的,但它非常俗气。你可能想看看这篇文章。

于 2012-05-31T00:55:43.740 回答
0

你试图做的事情是不可能的。即使您覆盖this它也不会影响任何持有对该实例的引用的变量。并且在它上面调用一个函数仍然会有正确的this.

你唯一能做的就是在你的destroy函数中设置一个变量,这将使任何其他函数在调用时抛出异常。但这将是一个坏主意,因为它会减慢速度(好吧,这可以忽略不计),并且您可以在您的班级的文档中放入它在destroy()被调用后不应再使用的文档。

于 2012-05-31T00:43:34.080 回答
0

这可行,但它要求您知道new Klass()实例化的变量的名称:

function Klass() {};

Klass.prototype = {
  init: function() {
    //
  },
  destroy: function() {
    // Delete the variable that references the instance of the constructor.
    delete window.k;
  }
};

k = new Klass();
k.destroy();
console.log(k);

如果k变量被命名为其他任何名称,则它不起作用:

// Won't work.
u = new Klass();
u.destroy();

它还假设局部变量k确实在全局范围内。如果它在一个函数内部,它也不会工作。例如:

// Won't work.
var fn = function() {
  k = new Klass();
  k.destroy();
};

最后,它假定对象的浏览器环境window

于 2012-05-31T00:51:49.563 回答