我最近熟悉了显示模块模式 (RMP),并且我已经阅读了很多关于它的文章。
这似乎是一个非常好的模式,我想开始在一个大项目中使用它。在我正在使用的项目中:Jquery、KO、requireJS、Jquery Mobile、JayData。在我看来,它非常适合 KO ViewModels。
具体来说,我想使用它的这个版本。
我找不到的一件事是使用这种模式的缺点,是因为没有(我很难相信)吗?
在开始使用它之前我应该考虑什么?
我最近熟悉了显示模块模式 (RMP),并且我已经阅读了很多关于它的文章。
这似乎是一个非常好的模式,我想开始在一个大项目中使用它。在我正在使用的项目中:Jquery、KO、requireJS、Jquery Mobile、JayData。在我看来,它非常适合 KO ViewModels。
具体来说,我想使用它的这个版本。
我找不到的一件事是使用这种模式的缺点,是因为没有(我很难相信)吗?
在开始使用它之前我应该考虑什么?
显示模块模式 (RMP) 创建的对象在覆盖方面表现不佳。因此,使用 RMP 制作的对象不能很好地用作原型。因此,如果您使用 RMP 创建将在继承链中使用的对象,请不要这样做。这个观点是我自己的观点,与那些揭示原型模式的支持者相反。
要查看不良继承行为,请使用以下 url 构建器示例:
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"
将行为与以下 url builder 实现进行对比
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/
我阅读了@nemesv 引用我的文章(谢谢:)),我认为还有一个没有提到的缺点,所以我想我会在这里添加它以供参考。这是文章的引述:
缺点
这种模式的一个缺点是,如果一个私有函数引用一个公共函数,那么如果需要补丁,这个公共函数就不能被覆盖。这是因为私有函数将继续引用私有实现,并且该模式不适用于公共成员,仅适用于函数。
引用私有变量的公共对象成员也受上述无补丁规则注释的约束。
因此,使用 Revealing Module 模式创建的模块可能比使用原始 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
}());
这将覆盖你的继承。