为什么Javascript Singleton是这样编写的?

时间:2016-05-16 12:51:50

标签: javascript design-patterns

我到处都看到了以这种方式在javascript中实现单例:

var Singleton = (function () {
    var instance;

    function createInstance() {
        var object = new Object("I am the instance");
        return object;
    }

    return {
        getInstance: function () {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

在这里我们可以看到它返回一个函数,我们必须调用它来获取一个对象。 问题:为什么我们不能这样写:

var Singleton = (function () {

    function privateMethod() {
        ...
    }

    return {
        publicMethod1: function() { },
        publicMethod2: function() { },
    };
})();

有人会说原因是继承支持。但是,我没有看到任何区别。无论如何,Singleton现在是一个对象。

2 个答案:

答案 0 :(得分:2)

有趣的问题,我会尝试猜测。

我看到了几个原因:

  • @Steffomio首先在评论中指出 第一个版本将仅在第一次使用时进行实例化,而第二个版本将立即实例化,这可能导致CPU加载页面负载(通常是不必要的影响)

  • 第二个在这里:

     if (!instance) {
            instance = createInstance();
        }
        return instance;
    

部分代码。

使用您的代码版本(简单的闭包评估),如果单例的脚本在网页中多次嵌入,则可能会失败。
第一次创建singletong,然后一些代码行修改它,然后另一行重新创建单例,并且先前的修改丢失。

  • 第三个原因是许多语言无法像在JavaScript中一样轻松地表达自动评估函数。如果你看看如何在C#中实现单例,你会发现一个类似的pattern,它可能经常被翻译成JavaScript。

  • 最后的原因是继承支持,正如你所说的那样。

答案 1 :(得分:0)

你可以像这样使用模块显示模式。

var Singleton = Singleton || function () {

    var privateMethod1 = function() {
        ...
    }

    var privateMethod2 = function() {
        ...
    }


    return {
        publicMethod1: privateMethod1,
        publicMethod2: privateMethod2 
    };
}();

关闭的方式,这个方法只会在你的应用程序中加载一次,它将保留对你的方法的引用。

您不需要创建Singleton实例(新的Singleton - >不需要)

您可以直接调用Singleton.publicMethod1()