我最近正在读《学习JavaScript设计模式》这本书。我没有得到的是模块模式和显示模块模式之间的区别。我觉得他们是同一回事。有人可以举一个例子吗?
至少有三种不同的方式来实现模块模式,但是显示模块模式是唯一具有正式名称的模块模式后代。
模块模式必须满足以下条件:
但是这个定义有很多歧义。通过以不同方式解决歧义,您可以获得模块模式的变体。
显示模块模式是“模块模式”变体中最著名和最受欢迎的模块。与其他替代方案相比,它具有许多优势,例如
RMP除了原始条件外还满足其他三个条件:
以下示例显示了其用法
var welcomeModule = (function(){
var name = "John";
var hello = function(){ console.log("Hello, " + name + "!");}
var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return {
name: name,
sayHello: hello,
sayWelcome: welcome
}
})();
如果你想使name
和sayHello
私有的,你只需要注释掉返回对象相应行。
var welcomeModule = (function(){
var name = "John";
var hello = function(){ console.log("Hello, " + name + "!");}
var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return {
//name: name,
//sayHello: hello,
sayWelcome: welcome
}
})();
这可能是模块模式的最旧的变体。与RMP不同,此变体没有性感的正式名称。
除了原始条件外,它还满足以下条件:
this
只要有可能,都通过via引用公共成员。在以下示例中,您可以看到与RMP相比,函数定义实际上是在返回对象文字中,而对成员的引用由限定this
。
var welcomeModule = (function(){
return {
name: "John",
sayHello: function(){ console.log("Hello, " + this.name + "!");}
sayWelcome: function() { console.log( this.hello() + " Welcome to StackOverflow!");}
}
})();
请注意,与RMP一样,为了生成name
和sayHello
私有化,指向name
和指向sayHello
各种函数体定义的引用也必须更改。
var welcomeModule = (function(){
var name: "John";
var sayHello = function(){ console.log("Hello, " + name + "!");};
return {
//name: "John",
//sayHello: function(){ console.log("Hello, " + this.name + "!");}
sayWelcome: function() { console.log( hello() + " Welcome to StackOverflow!");}
}
})();
此变体也没有正式名称。
除了原始条件外,它还满足以下条件:
使用我们的旧示例,您可以看到公共成员被直接添加到存根对象中。
var welcomeModule = (function(){
var stub = {};
stub.name = "John";
stub.sayHello = function(){ console.log("Hello, " + stub.name + "!");}
stub.sayWelcome = function() { console.log( stub.hello() + " Welcome to StackOverflow!");}
return stub;
})();
如果你想name
和sayHello
私人像以前一样,到现在,私有成员的引用必须改变。
var welcomeModule = (function(){
var stub = {};
var name = "John";
var sayHello = function(){ console.log("Hello, " + name + "!");}
stub.sayWelcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return stub;
})();
显示模块模式与模块模式的其他变体之间的区别主要在于如何引用公共成员。结果,RMP更易于使用和修改,这也说明了它的流行性。但是,(我认为)这些优势付出了巨大的代价,艾迪·奥斯曼尼(Addy Osmani)在“ 揭示模块模式”一文中提到了这一点,
这种模式的缺点是,如果私有函数引用了公共函数,则在需要补丁的情况下不能覆盖该公共函数。这是因为私有函数将继续引用私有实现,并且该模式不适用于公共成员,仅适用于函数。
引用私有变量的公共对象成员也应遵守上面的无补丁规则说明。
因此,使用“显示模块”模式创建的模块可能比使用原始“模块”模式创建的模块更脆弱,因此在使用过程中应格外小心。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句