揭示模块模式和简单构造函数之间的区别

Difference between Revealing Module Pattern and simple Constructor

用谷歌搜索但没有找到合适的资源来解释使用 Revealing Module Pattern 和 this 关键字之间的区别。

当使用显示模块模式时,我可以有以下代码:

var moduleRevealing = function() {
    var talk = function() {
      console.log("Talking....");
    };
    var walk = function() {
      console.log("Walking...");
    };
    return {
      talk: talk,
      walk: walk
    }
  };

  console.log('Module Pattern Object');
  console.log(moduleRevealing());

现在可以使用 this 关键字实现相同的效果,如下所示:

var module = function() {
    var talk = function() {
      console.log("Talking....");
    };
    this.walk = function() {
      console.log("Walking...");
    };
    this.talk = talk;
  };
  var mod1 = new module();
  console.log('Module Object');
  console.log(mod1);

两者有何不同?我只能看到一个区别,那就是 __proto;前者指向Object,后者指向module.

万一有人想看代码 - Fiddle

在您的示例中,实际上没有区别(除了 constructor 等的细微差别)两者都是 return 一个对象,每个方法都附加了一个新副本。如果 talkwalkmodule.prototype 的一部分,那就不一样了。

在您的简单示例中没有区别,但让我稍微复杂一点。

var moduleRevealing = function() {
    var talk = function() {
      console.log("Talking....");
    };
    var walk = function() {
      console.log("Walking...");
    };
    var walkAndTalk = function(){
      walk();
      talk();
    };
    return {
      talk: talk,
      walk: walk,
      walkAndTalk: walkAndTalk
    }
  };

使用 this

var module = function() {
    var talk = function() {
      console.log("Talking....");
    };
    this.walk = function() {
      console.log("Walking...");
    };
    this.talk = talk;
    this.walkAndTalk = function(){
      this.walk();
      this.talk();
    }
  };

这两个稍微复杂一些的示例现在在您覆盖它们的方法时具有非常不同的行为。

var modR = moduleRevealing();
var mod1 = new module();
modR.walk = function() {console.log('FAST Walking...");}
mod1.walk = function() {console.log('FAST Walking...");}

modR.walk(); // outputs "FAST Walking..."
modl.walk(); // outputs "FAST Walking..."

modR.walkAndTalk(); // outputs "Walking ... Talking..."
mod1.walkAndTalk(); // outputs "FAST Walking...Talking..."

请注意,即使 walk() 的输出已更改,当您覆盖使用 Revealing Module 创建的实例时,依赖方法 walkAndTalk() 不会获取该更改。根本原因是 Revealing Module 模式鼓励那些懒得学习 this 的人不加选择地使用 javaScript 闭包。请参阅此 post of mine 以比较模块模式变体之间的差异。