这个观察者模式代码有什么问题?

时间:2016-08-01 23:06:53

标签: javascript design-patterns observer-pattern

我刚从https://scotch.io/bar-talk/4-javascript-design-patterns-you-should-know#observer-design-pattern尝试了这个观察者模式代码,但它不起作用。它告诉我 this.observers 未定义,但我真的不明白为什么?

以下是示例代码:

var Subject = function() {
this.observers = [];

return {
  subscribeObserver: function(observer) {
    this.observers.push(observer);
  },
  unsubscribeObserver: function(observer) {
    var index = this.observers.indexOf(observer);
    if(index > -1) {
      this.observers.splice(index, 1);
    }
  },
  notifyObserver: function(observer) {
    var index = this.observers.indexOf(observer);
    if(index > -1) {
      this.observers[index].notify(index);
    }
  },
  notifyAllObservers: function() {
    for(var i = 0; i < this.observers.length; i++){
      this.observers[i].notify(i);
    };
  }
};
};

var Observer = function() {
  return {
    notify: function(index) {
      console.log("Observer " + index + " is notified!");
    }
  }
}

var subject = new Subject();

var observer1 = new Observer();
var observer2 = new Observer();
var observer3 = new Observer();
var observer4 = new Observer();

subject.subscribeObserver(observer1);
subject.subscribeObserver(observer2);
subject.subscribeObserver(observer3);
subject.subscribeObserver(observer4);

subject.notifyObserver(observer2); // Observer 2 is notified!

subject.notifyAllObservers();
// Observer 1 is notified!
// Observer 2 is notified!
// Observer 3 is notified!
// Observer 4 is notified!

2 个答案:

答案 0 :(得分:1)

请检查 fiddle

var Subject = function() {

   this.observers = [];

   this.subscribeObserver = function(observer) {

   this.observers.push(observer);

},

   this.unsubscribeObserver = function(observer) {

    var index = this.observers.indexOf(observer);

      if(index > -1) {

         this.observers.splice(index, 1);

       }

},

   this.notifyObserver = function(observer) {

    var index = this.observers.indexOf(observer);

     if(index > -1) {

       this.observers[index].notify(index);

    }

},

    this.notifyAllObservers = function() {

       for(var i = 0; i < this.observers.length; i++){

        this.observers[i].notify(i);

   };

  }

};

var Observer = function() {

return {

    notify: function(index) {

       console.log("Observer " + index + " is notified!");

     }

   }

}

var subject = new Subject();

var observer1 = new Observer();
var observer2 = new Observer();
var observer3 = new Observer();
var observer4 = new Observer();

subject.subscribeObserver(observer1);
subject.subscribeObserver(observer2);
subject.subscribeObserver(observer3);
subject.subscribeObserver(observer4);

subject.notifyObserver(observer2); // Observer 2 is notified!

subject.notifyAllObservers();
// Observer 1 is notified!
// Observer 2 is notified!
// Observer 3 is notified!
// Observer 4 is notified!

在你的返回对象中,观察者是未定义的,这就是你无法访问本机方法“push”的原因。

答案 1 :(得分:0)

this.observers是未定义的,因为在返回的对象内部,这是指返回的对象{....},这是一个新创建的对象。

可以通过关闭作为您的Subject函数的父对象的对象来解决。

尝试以下代码:

var Subject = function () {
  this.observers = [];
  self = this;
  return {
    subscribeObserver: function (observer) {
      self.observers.push(observer);
    },
    unsubscribeObserver: function (observer) {
      var index = self.observers.indexOf(observer);
      if (index > -1) {
        self.observers.splice(index, 1);
      }
    },
    notifyObserver: function (observer) {
      var index = self.observers.indexOf(observer);
      if (index > -1) {
        self.observers[index].notify(index);
      }
    },
    notifyAllObservers: function () {
      for (var i = 0; i < this.observers.length; i++) {
        self.observers[i].notify(i);
      }
    },
  };
};

var Observer = function () {
  return {
    notify: function (index) {
      console.log("Observer " + index + " is notified!");
    },
  };
};

var subject = new Subject();

var observer1 = new Observer();
var observer2 = new Observer();
var observer3 = new Observer();
var observer4 = new Observer();

subject.subscribeObserver(observer1);
subject.subscribeObserver(observer2);
subject.subscribeObserver(observer3);
subject.subscribeObserver(observer4);

subject.notifyObserver(observer2); // Observer 2 is notified!