我最近熟悉了Revealing Module模式,并且我已经阅读了很多关于它的文章。
这似乎是一个非常好的模式,我想在我拥有的一个大项目中开始使用它。在我正在使用的项目中:Jquery,KO,requirejs,Jquery Mobile,JayData。在我看来它似乎非常适合KO ViewModels。
具体来说,我想使用THIS版本。
我找不到的一件事是使用这种模式的缺点,是因为没有(我觉得很难相信)?
在开始使用之前我应该考虑什么?
答案 0 :(得分:15)
Revealing Module Pattern(RMP)创建的对象在覆盖方面表现不佳。因此,使用RMP制作的对象不能很好地用作原型。因此,如果您正在使用RMP来创建将在继承链中使用的对象,那就不要。 这种观点是我自己的,与那些揭示原型模式的支持者相对立。
要查看错误的继承行为,请参阅以下网址构建器示例:
function rmpUrlBuilder(){
var _urlBase = "http://my.default.domain/";
var _build = function(relUrl){
return _urlBase + relUrl;
};
return {
urlBase: _urlBase,
build: _build
}
}
不考虑为什么要将RMP用于没有私有组件的对象的问题,请注意,如果你获取返回的对象并用“http://stackoverflow.com”覆盖urlBase,你会发现build()的行为适当改变。它没有,如下所示:
var builder = new rmpUrlBuilder();
builder.urlBase = "http://stackoverflow.com";
console.log(builder.build("/questions"); // prints "http://my.default.domain/questions" not "http://stackoverflow.com/questions"
将行为与以下网址构建器实现进行对比
function urlBuilder = function(){
return {
urlBase: "http://my.default.domain/".
build: function(relUrl){ return this.urlBase + relUrl;}
}
}
var builder = new urlBuilder();
builder.urlBase = "http://stackoverflow.com";
console.log(builder.build()); // prints "http://stackoverflow.com/questions"
行为正确。
您可以使用此范围更正显示模块模式的行为,如下所示
function rmpUrlBuilder(){
var _urlBase = "http://my.default.domain/";
var _build = function(relUrl){
return this.urlBase + relUrl;
};
return {
urlBase: _urlBase,
build: _build
}
}
但这相当违背了揭示模块模式的目的。有关详细信息,请参阅我的博文http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/
答案 1 :(得分:4)
我读过@nemesv引用我的文章(谢谢:))我认为还有一个未提及的缺点,所以我想我会在这里添加它以供参考。以下是文章的引用:
缺点
这种模式的缺点是如果私有函数引用 一个公共函数,如果一个补丁,公共函数不能被覆盖 有必要的。这是因为私人功能将继续 引用私有实现,该模式不适用于 公共成员,仅限于职能部门。
引用私有变量的公共对象成员也是 受上述无补丁规则的影响。
因此,使用Revealing Module模式创建模块 可能比使用原始模块创建的更脆弱 模式,所以在使用过程中应该小心。
我的补充:
您无法使用此模式的继承。例如:
var Obj = function(){
//do some constructor stuff
}
var InheritingObj = function(){
//do some constructor stuff
}
InheritingObj.prototype = new Obj();
InheritingObj.prototype.constructor = InheritingObj;
这是js中继承的一个简单示例,但在使用Revealing Prototype Pattern时,您需要执行此操作:
InheritingObj.prototype = (function(){
//some prototype stuff here
}());
会覆盖你的继承。
答案 2 :(得分:-2)
Revealing Module Pattern的其他缺点包括:
我建议在Revealing Module Pattern上使用Definitive Module Pattern (https://github.com/tfmontague/definitive-module-pattern)