简体   繁体   中英

How to have an instance delete itself from within a prototype function is JavaScript

If I have a JavaScript constructor function, and I set a destroy method on its prototype. Is it possible to delete (or at least unset) the instance from the destroy method? Here's an example of what I'm trying to do.

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

I understand that I can't simply do this = undefined from with the destroy method, but I thought I could get around that by using a timeout like so:

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

I thought the timeout function would have access to the instance via self from the closure (and it does), but that doesn't seem to work. If I console.log(self) from inside that function it shows up as undefined , but k in the global scope is still an instance of Klass .

Does anyone know how to make this work?

k is a reference that points out to an instance of Klass . when you call destroy as a method of Klass the this inside the function gets bound to the object you called a destroy method on. It now is another reference to that instance of Klass . The self that you close on in that little closure is yet another reference to that instance. When you set it to undefined you clear that reference, not the instance behind it. You can't really destroy that instance per se. You can forget about it (set all the references to undefined and you won't find it again) but that is as far as you can go.

That said, tell us what you want to accomplish with this and we'll be glad to help you find a solution.

Though deleting its own object instance is possible, it is very tacky. You might want to check out this article.

What you are trying to do is impossible. Even if you overwrite this it will not affect any variable holding a reference to that instance. And calling a function on it will still have the correct this .

The only thing you could do is setting a variable in your destroy function that will make any other function throw an exception when called. But that would be a bad idea since it would slow things down (ok, that's negligible) and you can just put in the docs of your class that it is not supposed to be used anymore after destroy() has been called.

This works, but it requires that you know what the name of variable to which the new Klass() is instantiated:

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);

If the k variable is named anything else it doesn't work:

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

It also assumes that the local variable k is really in the global scope. If it were inside a function it would not work either. For instance:

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

Finally it assumes a browser environment for the window object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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