【问题标题】:Revealing Module / Prototype Pattern显示模块/原型模式
【发布时间】:2014-06-30 10:37:36
【问题描述】:

直到现在,我都使用显示模块模式来构建我的 Javascript,如下所示:

     var module = (function() {
        var privateVar;

        // @public
        function publicFunction( ) {

        }       

        return {
            publicFunction: publicFunction
        }
    })();

Fiddle

虽然此代码按预期工作,但我最近阅读了一篇文章,如果您有多个实例,此模式会使用大量内存,并且与其他模式相比它存在一些速度问题。因为我喜欢使用这种模式,所以我搜索了没有所有这些“问题”的类似模式,并且遇到了 Revealing Prototype Pattern。据我所知,JavaScript 的 Prototype 有更好的内存管理。

现在我想知道使用显示原型模式是否更快/更好地记忆? This benchmark 让我感到惊讶,因为模块模式似乎要快得多。有什么理由吗?

另外,我不知道如何使用 Revealing Prototype Pattern 拥有多个实例(与上面的 Revealing Module Pattern Fiddle 相比):

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

    prototypeModule.prototype = function () {
        var privateVar;

        // @public
        function init( ) {            

        }  

        return {
            init: init
        }
    }();

Fiddle 2

我做错了什么?

【问题讨论】:

标签: javascript prototype revealing-module-pattern


【解决方案1】:

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

您在第一个 sn-p 中提供的代码是一个单例模块,没有“多个实例”。完全没问题。

只有在你的小提琴中命名为Module pattern - Multiple instances 的东西在实例化大量对象时才会受到memory disadvantages 的影响。但是请注意,这不是“模块模式”,而是“工厂模式”。

现在我想知道使用显示原型模式是否更快/更好地记忆?

一般来说,如果应用正确,是的。

This benchmark 让我感到惊讶,因为模块模式似乎要快得多。有什么原因吗?

他们模块的代码乱七八糟,无法修复。我什至不想评论那里发生的事情。

我也不知道如何使用显示原型模式创建多个实例

原型的好处是它的属性在所有实例之间共享。这意味着所有实例的.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 会变得很棘手。虽然this updated fiddle 有效,但我想知道是否有什么需要改进的地方?我可能可以将我的 init 函数重命名为例如addEventHandlers,因为在我看来,这部分 (var prototypeModule = function( el ) { /* INIT_HERE*/ };) 是我与其他模式相比的实际 init 函数?对吗?
  • 如果你想从原型函数访问它们,是的,你需要公共属性。或者你没有对所有东西都使用原型(共享)方法,但是有一些可以访问局部变量的特权方法。是的,构造函数是初始化函数,你不需要使用init()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2020-01-23
  • 2016-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多