是否可以将Revealing Module Pattern实例传递给回调函数?

时间:2012-10-11 19:38:32

标签: javascript revealing-module-pattern

我有一些使用Revealing Module Pattern的javascript,如下所示。它接受一个稍后调用的回调函数。我希望那个回调函数能够调用类中定义的函数,但它不起作用。

window.MyClass = function() {
  var self = this,

  start = function (callback) {
    callback(self);
  },

  cancel = function() {
    console.log('Cancel invoked');
  };

  return {
    start: start,
    cancel: cancel
  };
};

var myCallbackFunction = function(instance) {
  instance.cancel(); // Error: instance.cancel is not a function
};

var obj = new window.MyClass();
obj.start(myCallbackFunction);

我可以将这个样本重新修改为Revealing Prototype Pattern并且它按预期工作,所以我的问题是我可以使用RMP来解决这个问题,还是只是这种模式的限制?

谢谢, 罗杰

2 个答案:

答案 0 :(得分:4)

window.MyClass = function() {
  var self = this;

  this.start = function (callback) {
    callback(self);
  };

  this.cancel = function() {
    console.log('Cancel invoked');
  };

  return {
    start: this.start,
    cancel: this.cancel
  };
};

然后,它既是实例方法,也可以通过返回值获得。

但是对于这个简单的东西(例如没有私有变量),我会使用一个直接原型(" Prototype Pattern")。

顺便说一下,如果你正在阅读this series,你应该知道这些并不是真正的标准术语。

他还说,"虽然JavaScript不像C#或Java那样设计了类或面向对象编程的概念,但通过一些工作,您可以获得类似的结果。"实际上,JavaScript是为面向对象编程而设计的,但它是基于原型的。正如您所见,它还具有足够的灵活性以允许替代方案;在某些情况下,这些替代方案肯定更好。

你甚至不需要自己,因为你的对象一定会受到束缚。

所以:

window.MyClass = function(){};

window.MyClass.prototype = {
    start: function (callback) {
        callback(this);
    },

    cancel: function () {
        console.log('Cancel invoked');
    }
};


var myCallbackFunction = function(instance) {
  instance.cancel();
};

var obj = new window.MyClass();
obj.start(myCallbackFunction);

答案 1 :(得分:1)

永远不要从构造函数返回对象。这是奇怪的JS怪癖之一。

您没有获得MyClass的实例,而是获得了一个普通对象。当构造函数返回一个对象时,该对象将返回而不是将返回的实例。

// good!
function MyClass() {};
new MyClass().constructor // returns: function MyClass() {}
new MyClass().constructor == MyClass // true

// bad!
function MyClass() { return {a:123}; };
new MyClass().constructor // returns: function Object() { [native code] }
new MyClass().constructor == MyClass // false

简而言之,古典风格和揭示模块风格并不能很好地融合。

在您的情况下,任何分配给this属性的函数都是向外部显示该函数。所以也许你想要这个。

window.MyClass = function() {
  var self = this;

  var start = function (callback) {
    callback(self);
  };

  var cancel = function() {
    somePrivateFn();
    console.log('Cancel invoked');
  };

  var somePrivateFn = function() {
    console.log('private function!');
  };

  this.start = start;
  this.cancel = cancel;
};

但是如果你不需要任何私密的东西(你的例子揭示了一切,那么没有什么是私有的)使用像Matthew建议的基于原型的方法,这在所有方面都更快更简单。