如何将模块单例JavaScript转换为支持实例?

如何将模块单例JavaScript转换为支持实例?,javascript,oop,module-pattern,Javascript,Oop,Module Pattern,我一直在编写一个应用程序,我已经成功地将不同的功能划分为所谓的“模块”模式,其中有一个具有公共和私有成员的自动执行单例 var WidgetModule = (function($, options) { // Private variable var someVar; // Private functions function somePrivateFunction() { } // Define the public members

我一直在编写一个应用程序,我已经成功地将不同的功能划分为所谓的“模块”模式,其中有一个具有公共和私有成员的自动执行单例

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);
我现在遇到了一个案例,我有几个模块,我希望能够创建多个实例

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

这个呢:

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

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

用法:

var w = new Widget({someOption: "here"});
如您所见,您可以在构造函数创建的所有实例之间共享私有数据,如果您真的愿意,您可以拥有仅与某些select实例函数共享的私有数据。这些函数必须在构造函数中创建,这具有重用含义,而不需要真正私有实例数据的函数可以在原型中创建,因此所有实例都可以共享

更好的是,由于您已经有了一个方便的作用域函数,您可以通过为公共函数指定实际名称:

    pubs.init = Widget_init;
    function Widget_init() {

    }

实际上,我并没有对上面的内容进行编码,因为我定义了一个助手工厂,使其更加简洁(并使功能的专门化更加容易,比如
汽车
汽车
继承功能)

@TJ我的例子是不是太简单了,缺少了什么?Tx@Mic:我将对您的答案发表评论。为什么将jQuery作为$传入?它不是已经可以通过$访问了吗?我有点像JS noob,所以我假设有什么我不明白的地方。@AaronLS:“为什么将jQuery作为$传递?它不是已经可以通过$访问了吗?”不一定,jQuery有一个。由于插件本质上是在作者无法控制的环境中使用的,因此必须考虑到它……在对我的回答的评论中,您问您是否缺少一些东西。从根本上说,它是有效的,并且应该有您显示的输出。但是,它没有任何
WidgetModule
范围(只是实例级范围),因此没有机会在实例之间共享数据或函数(在基于类的系统中,您称之为“类”级方法/数据)。每个实例都有自己的所有内容(包括函数实现)的副本。这对于模块和类似的东西来说是很好的,但是对于您将要拥有很多的对象,您希望在您可以共享的地方共享它们。(续)(续)JavaScript有完整的原型机制来实现这一点(重用东西)。以上也有点不寻常,;人们希望通过
new
(例如,
var w1=new-WidgetModule({id:1});
)调用工厂。如果您通过
new
调用它,它会工作,但会丢弃由
new
创建的对象,取而代之的是您返回的对象;一点内存搅动(可能基本上是无害的)。上述操作也会中断
instanceof
w1 instanceof WidgetModule
将为false)。我最讨厌的是,
init
someFunction
是匿名的。但它是有效的,我也见过它以前提倡的模式。最好的,
    pubs.init = Widget_init;
    function Widget_init() {

    }