如何在JavaScript中实现引用计数?

时间:2015-12-09 10:00:11

标签: javascript constructor destructor javascript-objects reference-counting

如何在JavaScript中实现引用计数? 目的是在创建第一个实例或销毁最后一个实例时触发构造函数/析构函数。

我需要实现三种类:abstract,singleton和normal(继承或不继承)。

我试图实现包含所有实例的数组的类ClassDispatcher,但删除它们不会删除引用...

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

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

1 个答案:

答案 0 :(得分:2)

你不能。为了完成您所描述的内容,您必须能够在对象即将被垃圾收集或者释放对其的最后一个引用时从JavaScript引擎接收回调。没有这样的回调。

最好的选择:查看设计的大图,找到一种不需要这样做的方法。新的ES2015 WeakMap和/或WeakSet对象在更大的设计中可能会有用。

非常远程第二好的替代:如果您可以要求对象的用户调用方法,例如destroy,那么他们认为他们已完成引用该对象,您可以这样做,但由于使用错误(无法调用destroy),非常容易失败。

这是非常容易失败的例子:

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

但是再次非常容易失败。 可以工作(看看任何编写得很好的C程序,它必须以一种简单的方式管理它的内存),但正确地做它很棘手(看看C中数以百万计的与内存相关的错误)程序)。