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



我一直在编写一个应用程序,并且我成功地将不同的功能分解为所谓的"模块"模式,在该模式中,您有一个具有公共和私有成员的自动执行单例。

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);

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

我知道这种模式

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

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

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"});

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

更好的是,由于您已经有一个方便的作用域函数,您可以通过为您的公共函数提供实际名称来帮助您的工具:

    pubs.init = Widget_init;
    function Widget_init() {
    }

我实际上并没有编写上述代码,因为我定义了一个帮助程序工厂,使其更加简洁(并且更容易进行功能专用化,例如从Vehicle继承功能的Car);详细信息在这里。

这个呢:

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

最新更新