【问题标题】:How to implement reference-counting in JavaScript?如何在 JavaScript 中实现引用计数?
【发布时间】:2016-03-14 13:12:21
【问题描述】:

如何在 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;

【问题讨论】:

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


    【解决方案1】:

    你不能。为了执行您所描述的操作,您必须能够在对象即将被垃圾收集或释放对它的最后一个引用时接收来自 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 中数百万与内存相关的错误)程序)。

    【讨论】:

    • ES2015 看起来很有希望。有真正的构造函数,但是析构函数呢?它们有什么标准语法,还是我应该自己实现它们?
    • @LukaszB:JavaScript 从第一天开始就有真正的构造函数。它没有析构函数或终结函数,甚至在 ES2015 中也没有。再说一次,上面的主要建议是重新设计,这样你就不需要它们了。如果做不到这一点,请强制您的 API 用户调用 destroy,并为他们做好准备 A) 忘记这样做,以及 B) 多次这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    相关资源
    最近更新 更多