如何将Module-Singleton JavaScript转换为支持实例?

时间:2011-05-16 21:13:13

标签: javascript oop module-pattern

我一直在编写一个应用程序,并且我已经取得了很多成功,将不同的功能分解为所谓的“模块”模式,在这种模式中,你有一个自行执行的单例,包含公共和私人成员。

var WidgetModule = (function($, options) {

    // Private variable
    var someVar;

    // Private functions
    function somePrivateFunction() {

    }

    // Define the public members
    var self = {
        init: function() {

        },
        someFunction: function() {

        }
    };

    return self;

})(jQuery, options);

我现在遇到一个案例,我有几个模块,我希望能够创建多个实例。

我知道这个模式是基于单例的,但我想知道是否有一种无痛的方法来修改这个模式以支持创建它们的实例?

2 个答案:

答案 0 :(得分:8)

当我需要多个对象的常用功能时,这里是我经常使用的模式(根据您提供的代码进行调整):

var Widget = (function($) {
    var pubs = Widget.prototype;

    // Private variable -- global to all instances
    var someVar;

    // The constructor    
    function Widget(options) {
        var privateInstanceVar;

        this.privateInstanceFunc = function() {
            return privateInstanceVar;
        };
    }

    // Private functions -- global to all instances
    function somePrivateFunction() {

    }

    // Define the public members
    pubs.init = function() {

    };

    pubs.someFunction = function() {

    };

    return Widget;

})(jQuery);

用法:

var w = new Widget({someOption: "here"});

如您所见,您可以在构造函数创建的所有实例之间共享私有数据,如果您真的想要,您可以拥有仅与某些选择实例函数共享的私有数据。这些函数必须在构造函数中创建,它具有重用含义,而不需要真正私有实例数据的函数可以在原型上,因此可以由所有实例共享。

更好的是,既然你已经有了一个方便的范围界定功能,你可以help your tools help you给你的公共函数实际名称:

    pubs.init = Widget_init;
    function Widget_init() {

    }

我实际上并没有真正编写上面的代码,因为我已经定义了一个帮助工厂,它使它更简洁(并且更容易进行功能的特化,比如CarVehicle继承功能{1}}); details here

答案 1 :(得分:0)

这个怎么样:

function WidgetModule(options){
    //var $ = jQuery;
    // Private variable
    var someVar;

    // Private functions
    function somePrivateFunction() {

    }

    // Define the public members
    var self = {
        init: function() {
          console.log(options.id);
        },
        someFunction: function() {

        }
    };

    return self;
}

var w1 = WidgetModule({id:1}),
    w2 = WidgetModule({id:2});

w1.init(); // --> 1
w2.init(); // --> 2