Define a one-to-many dependency between objects so that when one object
changes state, all its dependents are notified and updated
automatically.
This is one of the most famous design pattern for JavaScript applications. It offers a model with subscription feature where the objects are being subscribed with an event and whenever an event occurs the subscribed object is notified. This is the cutting edge technology when working with the event driven programming. Its a loosely coupled design and provides a better object oriented approach.
In an application many event handlers are created which are triggered on an event. These handlers receive the event arguments with all the details of the triggered event like onClick, onLoad etc. In simpler words observer pattern is also known as publication/subscription or pub/sub model. Normally we add the event handlers by using addEventListener
or jQuery methods: on
, delegate
, live
, click
, etc…
In the language of engineers the observer pattern facilitates a Subject to publish the changes to one or more Observers. The subject hold the reference of all the observers and by using this reference it notifies the observer.
Diagram

Participants
The participants for this pattern are:
-
Subject - In sample code: Click
- Holds the observer reference. Can have multiple observers for the same update
- Facilitates the observer to subscribe or unsubscribe at any point of time
- Notifies the observers whenever any update is made
-
Observers - In sample code: clickHandler
- Hols a signature method which is called when a subject is updated
Wanna Try The Code
The mySubject is the subject and the myHandlers is the observer. The following code shows how to subscribe, unsubscribe and re-subscribe when the event is triggered. The observer receives notification from eventOne and eventThree only.
Notice that trigger method takes two arguments. first one is the event details and second about the context. If no context is passed then it defaults to the window.
function mySubject() {
this.myHandlers = []; // observers
}
mySubject .prototype = {
subscribe: function(fn) {
this.myHandlers.push(fn);
},
unsubscribe: function(fn) {
this.myHandlers = this.myHandlers.filter(
function(item) {
if (item !== fn) {
return item;
}
}
);
},
fire: function(o, thisObj) {
var scope = thisObj || window;
this.myHandlers.forEach(function(item) {
item.call(scope, o);
});
}
}
// log helper
var log = (function() {
var log = "";
return {
add: function(msg) { log += msg + "\n"; },
show: function() { alert(log); log = ""; }
}
})();
function run() {
var clickHandler = function(item) {
log.add("fired: " + item);
};
var subj = new mySubject();
subj.subscribe(clickHandler);
subj.fire('eventOne');
subj.unsubscribe(clickHandler);
subj.fire('eventTwo');
subj.subscribe(clickHandler);
subj.fire('eventThree');
log.show();
}
Advantages
- Helps to manage dependencies
- Requires a deeper bonding of relationship between the various modules/components of the application
- Its a decoupled approach which promotes the smaller and reusable components
Disadvantages
- Checking the integrity of your application can become difficult
- Switching a subscriber from one publisher to another can be costly
When to Use