Javascript:模块模式与构造器/原型模式?


77

我想知道模块模式或Constructor / protoType模式是否更适合我的工作。

基本上,我使用的是不引人注目的javascript-HTML文档具有对.js文件的引用。

我对模块模式的理解:

  • 调用INIT方法(基本上是一个公共方法,我可以使用模块模式创建和返回)
  • 在INIT方法中,分配所有点击事件等。

这听起来很适合我的情况,因为我不需要创建对象和继承层次结构等。

我对构造函数/原型模式的理解:

  • 用于创建对象
  • 用于使用继承(即超类型的子类型)

我是对的,对于提供简洁的JavaScript,模块模式是理想的吗?

Answers:


69

构造函数和原型是实现类和实例的合理方法之一。它们并不完全对应于该模型,因此您通常需要选择特定的方案或辅助方法以根据原型实现类。(有关JS类的一些背景知识。)

模块模式通常用于命名空间,在这里,您将有一个实例作为存储来对相关功能和对象进行分组。这是与原型开发不同的用例。他们彼此之间并不是真正的竞争。您可以很高兴地将两者一起使用(例如,将构造函数放到模块中并说new MyNamespace.MyModule.MyClass(arguments))。


1
所以就我而言,我真的不想创建实例,因此模块模式可能是我想要的理想选择。当您说命名空间时。我如何在模块模式中命名空间?我看到了使用YUI的一种方法-但这真的有必要吗?
马丁2010年

16
没有什么特别的技巧,您只需使用JavaScriptObject作为查找即可。可以直接创建var MyModule= { someProperty: 3, someFunction: function() { ... }, somethingElse: null };或分配给的对象文字MyModule.someFunction= function() { ... };。如果您想要私有变量,则可以在立即调用的函数表达式中进行操作,并return在闭包中放置一个对象...就我个人而言,“真正的”私有变量完全浪费时间。
bobince 2010年

1
js包含类的想法可能会令人误解-这是一本关于您不懂JS的极好的书| This&Object Prototypes-尽管ES6支持“类”,但是这些基本上只是对原型功能的掩盖,在您认为Java或C#类会导致您失望的意义上将它们视为类。混乱之路。当使用原型时,我建议按照上面链接的书的第6章中所述的OOLO模式。
约旦

1
我还建议js继承的概念有点用词不当,而委托是一个更好的术语:chipersoft.com/p/inheritance。我同意模块模式对于使复杂的应用程序保持良好的分离非常有用,但是有很多很好的案例可以使用模块模式进行组合/扩充,尤其是当您与对js不太熟悉的开发人员一起工作时-他们可能会更容易要了解一个IIFE什么是对(真的)了解原型:adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
乔丹

5
@bobince我知道您很久以前发布了此文章,但是为什么您发现真正的私有变量却浪费时间呢?
PDN

13

到目前为止,模块模式比原型更容易,更优雅。但是,首先考虑移动。这与大中型对象无关,因为初始化需要在启动之前解析整个块。多个闭包还会创建垃圾回收器不会释放的循环依赖项(尤其是IE),这会导致直到窗口(或选项卡)关闭后才释放更大的内存占用-检查chrome任务管理器进行比较-加载时间相反使用模块模式与对象大小成正比,而原型继承则不是这种情况。上面的陈述通过这样的多个基准进行了验证:http : //jsperf.com/prototypal-performance/54

如上次测试所示。小对象最好被初始化为普通对象(没有这些模式)。它适用于不需要关闭或继承的单个对象。评估您是否甚至需要这些模式是明智的。


4

原型模式可以帮助我们扩展功能,并且内存中只有一个功能实例,而与对象数量无关。在模块模式中,每个对象都在内存中创建函数的新实例,但是它提供了私有/公共变量的概念,并有助于封装变量和函数。


允许使用私有成员的Douglas crockfords特权类方法怎么样?
wayofthefuture 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.