这种模式的缺点是,如果一个私有函数引用了一个公共函数,那么如果需要修补程序,该公共函数就无法被覆盖。这是因为私有函数将继续引用私有实现,而该模式仅适用于公共成员,而不适用于函数。
有人能举个例子吗? 链接到上面提到的揭示模式
有人能举个例子吗? 链接到上面提到的揭示模式
将使用对象字面量创建的对象与使用Revealing Module模式创建的对象进行比较。
这是一个使用对象字面量创建的对象示例。
function makeGreeter(name){
return {
getName: function(){ return name;},
sayHello: function(){console.log("Hello, " + this.getName());}
}
}
var greeter = makeGreeter("Danny");
greeter.sayHello; // "Hello, Danny"
greeter.getName = function(){ return "George";}
greeter.sayHello(); // "Hello, George"
当你在返回对象上重写公共方法getName
时,依赖于getName
的sayHello
方法会受到更改的影响。这是因为在对象字面量风格中,对公共函数的引用是通过this
即返回的对象来完成的。
然而,当你使用揭示模块模式时,
function makeGreeter(name){
var getName = function(){ return name;},
sayHello = function(){console.log("Hello, " + getName());};
return {
getName: getName,
sayHello: sayHello
}
}
var greeter = makeGreeter("Danny");
greeter.sayHello; // "Hello, Danny"
greeter.getName = function(){ return "George";}
greeter.sayHello(); // "Hello, Danny"
RMP问候者不会调用公共getName
方法的覆盖,因为当RMP函数引用其他函数(包括公共和私有函数)时,它们引用私有闭包副本而不是附加到返回对象的公共函数。
正因为如此,我认为揭示模块模式是反模式。
@I-Lin Kuo给出的答案看起来不错,但是有一种情况会造成混淆。
function makeGreeter(name) {
return {
getName: function() {
return name;
},
sayHello: function() {
console.log("Hello," + this.getName());
}
}
}
var greeter = makeGreeter("Danny");
greeter.sayHello(); //"Hello,Danny"
greeter.getName = function() {
return "George";
}
greeter.sayHello(); //"Hello,George"
应该使用 greeter.sayHello()
而不是 greeter.sayHello
。这会造成很多混淆。
getName
绑定到这个位置,它似乎指向在RMP中返回的内容。function makeGreeter(name){
this.getName = function(){ return name;};
var _sayHello = function(){console.log("Hello, " + this.getName());};
return {
getName: getName,
sayHello: _sayHello
}
}
function makeGreeter(name){
this.getName = function(){ return name;};
var _sayHello = function(){console.log("Hello, " + this.getName());};
var API = {
getName: getName,
sayHello: _sayHello
};
return API;
}
myRevealingModule.increment = newFunction;
这样的操作并不会改变模块的内部工作方式。myRevealingModule.start
仍然会调用内部的私有增量函数。这可能是好的或者不好的,具体取决于上下文。 - Felix Kling