I have this code created with help from ChatGPT:
class Thing {
#intervalId;
#finalizationRegistry;
constructor() {
console.log('constructor()');
let count = 0;
this.#intervalId = setInterval(() => {
console.log(`Test ${count++}`);
}, 1000);
this.#finalizationRegistry = new FinalizationRegistry(() => {
this.#destructor();
});
this.#finalizationRegistry.register(this);
}
#destructor() {
console.log('destructor()');
clearInterval(this.#intervalId);
}
}
(() => {
const x = new Thing();
})();
This is my attempt to create a destructor for a class in JavaScript. I’m not sure if it works because the console.log('destructor()');
was not called when I tested. My first code used a dummy object inside the constructor as a help value and that was working, it was triggering when I assigned x = null
but the code was wrong.
The above code is just the smallest possible example of clearing setInterval with FinalizationRegistry
but I’m not sure if it works.
Is there a way to test that this actually works and call destructor?
My real question is that I want to implement Cache class and I need to trigger this function inside interval:
this.#intervalId = setInterval(() => {
this.#prune();
}, 1000);
And I want to clear the timer when this is not accessible anymore. Like with the above code:
(() => {
const x = new Thing();
})();
Can you create an interval inside the class constructor that references this
and clear the interval when the object is garbage collected? Can the object even be garbage collected when intervals keep a reference to this? If not then is there a workaround?
2
Answers
I came up with this with hints from @Bergi:
I used WeakRef since I needed to call the
#prune
method (as stated in the question) since withoutthis
kept inside the function and the object was never garbage collected.It works in NodeJS when called with
node --expose-gc script.js
.Note that I think that real destructor is not possible and you need to have the code that clean up the class like clear of interval outside of the class.
This is not how you use a
FinalizationRegistry
.First off, note that JS doesn’t have proper destructors,
FinalizationRegistry
may run callbacks a lot later than you’d expect (or might never run them).Second, the code needs several changes to work (see comments):
A bit of advice (from own experience): don’t use ChatGPT to generate code, use it only as a thought starter and research ideas yourself. That is harder, but otherwise you’ll likely end up with some code that you don’t understand and which may be indefinitely wrong.