Since I've dealt in the past with JavaScript’s funky "object model", I assume there is no such thing as a destructor. My searches were mildly unsuccessful, so you guys are my last hope. How do you execute stuff upon instance destruction?
-
10Your use of the pejorative isn't going to get you very far here. There's nothing "funky" about JavaScript's "object model" (which should NOT be in quotes). Just because it's not what you're used to (probably "classical OO"), doesn't mean there's anything wrong with it. – Ethan Brown Mar 21 '14 at 18:07
-
There is not concept like that in javascript, what do you want to exactly achieve with that? – ncubica Mar 21 '14 at 18:08
-
43@EthanBrown quite some attitude you got there sir. Has it occurred to you that I may not necessarily mean that it's **wrong** by adding those quotes, rather than it's **not quite what we're used to** as nearly all other languages which have introduced object model have stuck to? – php_nub_qq Mar 21 '14 at 18:10
-
@ncubica I have an interval going on in an object, which I need to destroy in case the object is no longer referable ( deleted ) – php_nub_qq Mar 21 '14 at 18:12
-
Guys, see this link http://stackoverflow.com/questions/10112670/when-are-javascript-objects-destroyed#10112776 and Steve's answer – Amit Joki Mar 21 '14 at 18:13
-
2@php_nub_qq I suggest you ask a new question relating to that specific problem, which seems like it could get you more valuable insight into both how JS works and how your specific design might be done in a better way. – Marcus Stade Mar 21 '14 at 18:17
-
@macke thank you for the suggestion, I'll just delete this one as it just seems like one big mess! – php_nub_qq Mar 21 '14 at 18:19
-
Major necromancer here but since the accepted answer was that i aint possible, I decided to share my fix to this problem.Whenever I want to destroy an object I use try catch finally and execute the destructor on the finally phase. – pihh-rocks Apr 12 '17 at 08:15
-
Another alternative is to use the "loaner" design pattern which will look something similar to the `with` context manager in Python. See here https://pastebin.com/nuJvD0zR since I'm unable to post an answer b.c. the question is marked as a duplicate. If you're using a particular framework, there may be lifecycle hooks that offer a better solution such as, for example, Angular2 offers the ngOnDestroy() hook to detach listeners. – solstice333 May 16 '17 at 23:10
4 Answers
MDN is a nice resource for JS. No, there is nothing like calling a function when an object ceases.

- 5,588
- 2
- 30
- 43
-
1Thank you for clearing that out. Just as another quick question, is there any way I could destroy an instance from within the object? Like for example `delete this;`, which makes sense, but obviously doesn't work? – php_nub_qq Mar 21 '14 at 18:18
-
2Quick answer: No. not really. With a trick: o={ kill:function(){ window.o=null;} } – Thomas Junk Mar 21 '14 at 18:22
-
14Not all environments have a `window` variable, not every variable is global (ideally none is!) and there can be dozens of other references to that object. So the "trick" is basically useless. – a better oliver Oct 22 '15 at 12:31
-
57@ThomasJunk, Re "*Since JS is garbage collected so*".. Rubbish. **Java is garbage collected too and it offers destructors.** – Pacerier Mar 22 '17 at 23:51
-
-
6@ThomasJunk Swift is garbage collected too and it offers destructors. Neither C/C++ explicitly call a ```destructor```, nor swift. C++ call destructor when object goes out the scope.```destructor``` isn't deallocator, it's just do some clean up work and leave it to the language runtime. Swift maintaining reference count. Mostly garbage collection triggered on scope out too. Garbage collection is not the reason. It's just design problem. – AntiMoron May 18 '17 at 03:29
-
1Likewise C# is also has Garbage Collection and Destructors (& Dispose & Finalize!). Destructors are not just for freeing memory and other resources. For example, it would be useful (to me today) as a good place to adjust my internal storage "map" of displayed text lines when a particular input has completed for either of 2 reasons. – Zeek2 Oct 05 '17 at 07:36
-
3@AntiMoron Minor clarification, Swift is not garbage collected (at least not in the traditional sense). ARC does not have a process running in the background that collects objects when there is memory pressure or on a periodic bases as you get with Java, JavaScript and other GC based languages. Instead with ARC enabled Swift/Objective-C when an object reference is equal to zero the object is destroyed on the spot (aka the compiler inserts retain/release for you). – James Jones Feb 05 '18 at 23:53
-
4But wouldn't be easily implementable and useful to have a callback when an object reaches zero references? – tru7 Mar 06 '18 at 10:15
-
@AntiMoron, what you say about C++ isn't entirely correct. Stack-based objects (not allocated with new) have the destructor called when they go out of scope (which is ALSO when their memory is freed). Heap-based objects (allocated with new) have the destructor called when they are deleted. Which is also associated with freeing their memory and has nothing to do with the scope. It is more accurate to say that C++ destructors are called at the point the memory is freed for the class. – stuckj Jan 04 '21 at 21:31
-
2@Pacerier, I assume you mean Java's `finalize` method. It is SIMILAR to a C++ destructor in that it's called just before the memory for the object is freed. But, unlike C++ there are no hard guarantees that `finalize` will be called. E.g., if the program exits before the next GC cycle after an object reaches a zero reference count it will never have `finalize` called. Also, if the reference count never goes to zero, but I guess you'd kinda expect it wouldn't be called in that case. :) – stuckj Jan 04 '21 at 21:38
FinalizationRegistry might be what you need. It is not a destructor, but it executes a function once the object is garbage collected. In any case, this is what I wish I had find when I first came on here :)

- 175,061
- 34
- 275
- 318

- 333
- 3
- 7
Aside from the already-mentioned FinalizationRegistry
that provides support for non-deterministic finalization, there is (as of this writing, March 2023) a proposal in the works adding a deterministic, scope-based cleanup construct to the language: Explicit Resource Management. It may land in the standard in 2023 or perhaps 2024.
The syntax has undergone a number of iterations, but given that it’s already past stage-3 review, it’s unlikely to change much now. Here’s a demonstration wrapping URL.createObjectURL
:
class BlobURL {
#url = null;
constructor(blob) {
this.#url = URL.createObjectURL(blob);
}
toString() {
if (this.#url == null)
throw new TypeError("URL was already revoked");
return this.#url;
}
valueOf() {
return this.#url;
}
[Symbol.dispose]() {
URL.revokeObjectURL(this.#url);
this.#url = null;
}
}
const doIFeelLucky = (url) => {
// imagine some process here that
// uses the URL, but may throw
if (6 * Math.random() < 1)
throw new Error("seems I don't");
};
const processBlob = (blob) => {
using url = new BlobURL(blob);
doIFeelLucky(url);
// `url` is revoked when the function returns or throws
};
Ownership transfer is a bit clunky, as it requires creating a DisposableStack
to manage it:
const processBlobAndReturnItsURL = (blob) => {
using stack = new DisposableStack();
const url = stack.use(new BlobURL(blob));
doIFeelLucky(url); // if this throws, `url` will be revoked
stack.move(); // release ownership
return url; // `url` will be returned without being revoked
}
Other downsides: there is no support for destructuring (despite numerous suggestions made to allow it while the proposal proceeded), and the construct is not expressive enough to perform exception-catching like Python context managers (though whether that would actually make sense is debatable). Still, it’s marginally better than finally
, which is what we have now.

- 26,597
- 4
- 30
- 62
As of more recently, this link is of more use to answer this question. The most important part:
As of 2012, all modern browsers ship a mark-and-sweep garbage-collector.
...
Cycles are no longer a problem
In the first example above, after the function call returns, the two objects are no longer referenced by any resource that is reachable from the global object. Consequently, they will be found unreachable by the garbage collector and have their allocated memory reclaimed.
Limitation: Releasing memory manually
There are times when it would be convenient to manually decide when and what memory is released. In order to release the memory of an object, it needs to be made explicitly unreachable.
So as far as cyclic references goes, de[con]structors aren't really needed.
One cool trick I have thought of though, if you have cyclic references and you want easy manual control over deconstruction...
class Container {
constructor() {
this.thisRef = [ this ];
this.containee = new Containee({ containerRef: this.thisRef });
}
//Note: deconstructor is not an actual JS thing/keyword.
deconstructor() {
//Have to delete `this.thisRef[0]` and not `this.thisRef`, in
//order to ensure Containee's reference to Container is removed.
delete this.thisRef[0];
}
doSomething() {
}
}
class Containee {
constructor({ containerRef }) {
//Assumption here is, if the Container is destroyed, so will the Containee be
//destroyed. No need to delete containerRef, no need for a
//deconstructor function!
this.containerRef = containerRef;
}
someFunc() {
this.containerRef[0].doSomething();
}
}
let c = new Container();
...
//No cyclic references!
c.deconstructor();
So here, instead of the Containee class storing a direct reference to the Container instance, it stores a reference to a size 1 array containing the Container reference, which the Container instance itself can then delete itself from. The array, with the reference, is managed by Container.
But again, this isn't really needed, since garbage collection in all modern browsers is mark-and-sweep and can handle cyclic references.

- 5,839
- 1
- 51
- 72
-
Reclaiming memory of unused objects isn’t the only use of destructors. There are also things like closing sockets, removing temporary files, releasing FFI/WASM resources (those are not visible to the garbage collector), etc. So your questioning of the question’s premises is incorrect. And it’s not true (any more) that there are no destructor/disposal/finalization facilities in JS either. `FinalizationRegistry` is one, and soon `Symbol.dispose` will be another. – user3840170 Mar 09 '23 at 13:38
-
@user3840170 I never said it was the only use, hence "So as far as cyclic references goes..." In my experience JS would either assume that you'd manually handle deconstruction tasks or automatically handle them for you. "FSI/WASM" was likely an emerging and barely used JS technology at the time of my answer. I never questioned anything. You comment on an answer that's 2.5 years old, expecting more than is even feasible at the time, mischracaterize what I even said in multiple ways, all the while ignoring the brilliant solution I provided before JS even accommodated for this. Check yourself. – Andrew Mar 09 '23 at 20:05
-
By May 2020, node.js (where you need to close sockets, files, etc. which would make destructors useful) was already vibrant, and the `FinalizationRegistry` proposal was just about to be merged (so the WASM case was already anticipated too). The question doesn’t even mention reference cycles either, it is about destructors in general. And the GC of any engine new enough to implement classes would almost surely collect cycles (since `.prototype.constructor` is a pervasive source of them), making the ‘brilliant’ solution redundant. This was a rather lousy answer even for its time. – user3840170 Mar 13 '23 at 20:16