揭示模块 / 原型模式

5
到目前为止,我使用了揭示模块模式来构建我的Javascript,就像这样:

     var module = (function() {
        var privateVar;

        // @public
        function publicFunction( ) {

        }       

        return {
            publicFunction: publicFunction
        }
    })();

Fiddle

尽管这段代码按预期工作,但我最近读了一篇文章,指出如果你有多个实例,此模式会使用大量内存,并且与其他模式相比存在一些速度问题。因为我喜欢使用这种模式,所以我搜索了一些类似的模式,避免了所有这些“问题”,我发现了揭示原型模式。据我所知,JavaScript的原型具有更好的内存管理。

现在我想知道是否使用揭示原型模式更快/更好地管理内存? 这个基准测试让我感到惊讶,因为模块模式似乎要快得多。有什么原因吗?

此外,我无法弄清楚如何使用揭示原型模式拥有多个实例(与上面的揭示模块模式Fiddle进行比较):

    var prototypeModule = function( el ) {
        this.init( );
    };

    prototypeModule.prototype = function () {
        var privateVar;

        // @public
        function init( ) {            

        }  

        return {
            init: init
        }
    }();

小提琴 2

我做错了什么?


1
如果您想了解有关原型和构造函数的更多信息,可以查看此答案。最后附有一个实现实例特定受保护成员的链接。https://dev59.com/J2Qo5IYBdhLWcg3wbe5K#16063711 - HMR
1
如果你喜欢揭示模块模式,你也可以尝试使用明确模块模式来构建你的代码:https://github.com/tfmontague/definitive-module-pattern - tim-montague
1个回答

4

虽然这段代码按预期工作,但我最近读到一篇文章,如果有多个实例,此模式会使用大量内存。

您在第一个片段中呈现的代码是单例模块,没有“多个实例”。完全没问题。

只有您在fiddle中标题为Module pattern - Multiple instances的东西,当它实例化大量对象时会遭受内存缺陷。但请注意,这不是“模块模式”,而是“工厂模式”。

现在我想知道使用揭示原型模式是否更快/更省内存?

总的来说,如果正确应用,则是的。

这个基准测试让我感到惊讶,因为模块模式似乎要快得多。有什么原因吗?

他们的模块代码已经混乱到无法修复的程度。我甚至不尝试评论那里发生了什么。

此外,我无法弄清如何在显式原型模式下创建多个实例

原型的好处是其属性在所有实例之间共享。这意味着所有实例的 .init 方法指向同一个函数,该函数在其揭示模块作用域中具有单个 privateVar - 此变量仅对所有实例存在一次!它是静态的,而非实例特定的。

如果要使用原型,则无法访问真正的私有变量;您需要使用公共属性。但是,您的 clickFunction 需要一个本地(私有)变量来进行闭包,因此在此处不使用原型也没有问题:

function Constructor( el ) {
    var privateVar = $( el );
    privateVar.on( 'click', function clickFunction() {
        privateVar.addClass('click');
    });

    console.log( 'constructor: ' + privateVar.attr('id') ); 
}

谢谢!所以如果我理解正确,您是说我必须使用公共属性像 this.PROP 来代替私有变量?有没有更好的方法可以做到这一点,因为如果您正在使用类似 jQuery 事件处理程序之类的东西,this 就会变得棘手。虽然 这个更新后的 fiddle 可以工作,但我想知道是否有任何改进的空间?我可能可以将我的 init 函数重命名为例如 addEventHandlers,因为对我来说,这部分(var prototypeModule = function( el ) { /* INIT_HERE*/ };)是我的实际初始化函数,与其他模式相比是这样吗? - mrksbnch
1
如果你想从原型函数中访问它们,那么你将需要公共属性。或者你不使用原型(共享)方法来做所有的事情,而是有一些特权方法可以访问局部变量。而且,构造函数是初始化器函数,你不应该需要使用 init() - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接