2

How to implement reference-counting in JavaScript? Purpose is to fire constructor / destructor when first instance is created or last instance is destroyed.

I need to implement three kinds of classes: abstract, singleton, and normal (inherited or not).

I have tried to implement class ClassDispatcher containing arrays with all instances, but deleting them does not delete reference...

Module = function(parentModule)
{
    this.destroyInstance = function()
    {
        Module.prototype.referenceCounter--;
    }
    this.initInstance = function()
    {
        Module.prototype.referenceCounter++;
    }

    this.initInstance();
}
Module.prototype.referenceCounter = 0;

1 Answer 1

5

You can't. In order to do what you describe, you'd have to be able to receive a callback from the JavaScript engine when an object is about to be garbage-collected or when the last reference to it is released. There is no such callback.

Your best bet: Look at the larger picture of your design, to find a way not to need to do this. The new ES2015 WeakMap and/or WeakSet objects may be useful in that greater design.

Very much a distant second-best alternative: If you can require that users of your object call a method, for instance destroy, when they think they're done referencing the object, you could do it, but that would be very prone to failure because of usage errors (failing to call destroy).

Here's that very prone-to-failure example:

var CountedThing = (function() {
    var instances = 0;

    function CountedThing() {
        if (!this.hasOwnProperty("destroyed")) {
            ++instances;
            this.destroyed = false;
            if (instances === 1) {
                // First instance created
            }
        }
    }

    CountedThing.prototype.destroy = function() {
        if (!this.destroyed) {
            this.destroyed = true;
            --instances;
            if (instances === 0) {
                // Last instance "destroyed"
            }
        }
    }

    return CountedThing;
})();

But again, that's very prone to failure. It can work (look at any well-written C program, which has to manage its memory in a similear way), but doing it properly is tricky (look at the millions of memory-related bugs in C programs).

Sign up to request clarification or add additional context in comments.

2 Comments

ES2015 looks promising. There are real constructors, but how about destructors? Is there any standard syntax for them, or should i implement them by myself?
@LukaszB: JavaScript's had real constructors since day 1. It doesn't have destructors or finalizers, not even in ES2015. so again, The main advice above is redesign so you don't need them. Failing that, force users of your API to call destroy, and be prepared for them to A) Forget to do it, and B) Do it more than once.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.