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

Mit*_*rax 3 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);
Run Code Online (Sandbox Code Playgroud)

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

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

T.J*_*der 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);
Run Code Online (Sandbox Code Playgroud)

用法:

var w = new Widget({someOption: "here"});
Run Code Online (Sandbox Code Playgroud)

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

更好的是,既然您已经拥有一个方便的范围功能,您可以通过为您的公共函数提供实际名称来帮助您的工具帮助您:

    pubs.init = Widget_init;
    function Widget_init() {

    }
Run Code Online (Sandbox Code Playgroud)

我实际上并没有真正编写上面的代码,因为我已经定义了一个帮助工厂,它使它更简洁(并且更容易实现功能的特化,比如Car继承功能Vehicle); 这里详细介绍.

  • @AaronLS:*"为什么将jQuery作为$传递?是不是已经可以通过$访问了?"*不一定,jQuery有[无冲突模式](http://api.jquery.com/jQuery.noConflict/)其中`$`不用于jQuery.由于插件本质上是在作者无法控制的环境中使用的,因此必须允许它... (2认同)