【问题标题】:Revealing Module Pattern with a constructor用构造函数揭示模块模式
【发布时间】:2013-08-22 12:44:00
【问题描述】:

我在找出实现这一点的最佳方法时遇到了一些麻烦。

我想要一个具有构造函数的模块,该构造函数接受一个参数,该参数存储它以供以后在模块中使用。

var ModuleB = function(moduleA) {
    this.moduleA = moduleA;
}

ModuleB.prototype = function() {
    //private stuff/functions
    function someMethod() {
        moduleA.doSomething();
    }

    //public api
    return {
        someMethod : someMethod
    };
}();

在其他文件中

//ModuleA defined elsewhere
var moduleA = new ModuleA();

//...

var module = new ModuleB(moduleA);
module.someMethod();

现在在someMethod 中,moduleA 是未定义的,this 是全局窗口对象。有人可以解释我如何访问moduleA吗?我不明白构造函数之后this.moduleA = moduleA; 会发生什么。我不是真正的 javascript 开发人员,所以如果我在这里使用了错误的模式或其他什么,请随时加入。

【问题讨论】:

  • 我更新了示例以使其更清晰
  • @Chase 小提琴工作的唯一原因是因为moduleA 是全球性的。

标签: javascript revealing-module-pattern


【解决方案1】:

您非常接近,但您在someMethod 的定义中遗漏了一些重要的东西。

编辑:如果您在 ModuleB 中更改模块属性的名称,则更容易分辨哪些有效,哪些无效:

var ModuleA = function() {}

ModuleA.prototype = (function () {
    return {
        someMethod: function () {
            return 'foo';
        }
    };
}());

var ModuleB = function(moduleA) {
    this.innerModule = moduleA;
}

ModuleB.prototype = (function () {
    return {
        doStuff: function () {
            return this.innerModule.someMethod();
        }
    };
}());

var moduleA = new ModuleA();

var moduleB = new ModuleB(moduleA);
console.log(moduleB.doStuff()); // prints "foo"

http://jsfiddle.net/mN8ae/1/

【讨论】:

  • 谢谢你的例子。在我的实际情况中,“this”运算符并不总是 ModuleB 对象(idk,我猜可能是我的糟糕设计)。我可以在此实现中进行更改以使其适用于这些情况吗?或者我最好改变实现ModuleB的区域。此处示例jsfiddle.net/QKZxh/1
  • 原型上的函数应该总是有this指向调用对象
【解决方案2】:

试试这个:

var ModuleB = function(moduleA) {
    this.moduleA = moduleA;
}

// Simplifying your code, what was missin is the "this" keyword accessing the moduleA
ModuleB.prototype.someMethod = function() {       
   this.moduleA.doSomething();
};


var module1 = new ModuleB({ 
    doSomething: function(){ 
         alert('i do something'); 
    } 
});

module1.someMethod();

【讨论】:

  • 他的原型赋值是返回一个 IIFE(一个对象),而不是一个函数。
  • 是的,但是,一旦您创建了 ModuleB,它就会包含一个“原型”。如果覆盖整个对象,所有对 moduleA 的神奇引用都会丢失
  • moduleA是每个对象实例的一个属性,与原型无关。
  • 扩展@jbabey,moduleA在作为参数传递时成为给定对象的属性。因此,当作为参数传递时,javascript进程会看到ModuleA。 var ModuleB = function(moduleA) { var moduleA; this.moduleA = 模块A; }
【解决方案3】:

您需要使用 call/apply 来执行给定上下文的方法。

试试这个代码(我已经修改了你的代码)

var ModuleB = function(moduleA) {
     this.moduleA = moduleA;
      };

 ModuleB.prototype = function() {
     //private stuff/functions
     function someMethod() {

         this.doSomething();
     }

     //public api
     return {
         someMethod : someMethod
     }; }();


 var ModuleA=function(){
     this.doSomething=function(){
      alert('moduleA Method');   
     }; };

 var modA=new ModuleA(); var modB=new ModuleB(modA);
 modB.someMethod.call(modA);

谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多