JavaScript Observer Class
First off, let me be the 763rd person to say that JavaScript does not have have a formal class system, however it does have the expressive nature to represent the notion of a class. That being out of the way, this entry is about representing the Observer Pattern in JavaScript; otherwise known as the publisher/subscriber model. As some already might know, it is already well demonstrated in modern event handling BOM’s such as IE’s attachEvent or W3’s addEventListener which allow you to register multiple listeners, and notify each callback by firing one event.
You might also know that some JavaScript libraries such as Dojo, YUI, and Prototype have implemented generic utilities that easily allow you to set up your publishers and allow client code to subscribe to these events….
Well, here’s mine. It’s basic and to the point, and only uses a wee bit of code.
Observer Class
function Observer() {
this.fns = [];
}
Observer.prototype = {
subscribe : function(fn) {
this.fns.push(fn);
},
unsubscribe : function(fn) {
this.fns = this.fns.filter(
function(el) {
if ( el !== fn ) {
return el;
}
}
);
},
fire : function(o, thisObj) {
var scope = thisObj || window;
this.fns.forEach(
function(el) {
el.call(scope, o);
}
);
}
};
Take special note that a few of the extra array methods (filter and forEach) need to be added to supplement browsers that do not support them. You could just simply grab the two from here, or just grab them all from my minified collection.
Implementation
This part is easy.
subscribing and publishing
/*
* Publishers are in charge of "publishing" eg: Creating the Event
* They're also in charge of "notifying" (firing the event)
*/
var o = new Observer;
o.fire('here is my data');
/*
* Subscribers basically... "subscribe" (or listen)
* And once they've been "notified" their callback functions are invoked
*/
var fn = function() {
// my callback stuff
};
o.subscribe(fn);
/*
* Don't want to subscribe anymore?
*/
o.unsubscribe(fn);
Go ahead and have a play around. See it live in action (albeit a dull and boring illustration)




November 9th, 2006 at 3:14 am
Huzzah! Great post, short and no fuzz. When’s the next YUI demo screencast coming?
November 9th, 2006 at 3:34 am
Very interesting (and useful!)
Thanks for posting,
B!
November 9th, 2006 at 6:15 am
Why do you write
o.subscribe(fn)
Don’t should be something like
fn.registerObserver(o) ?
then you do o.fire();
don’t should be fn.notifyObserver();
http://en.wikipedia.org/wiki/Image:Observer-pattern-uml.jpg
should you explaining me, please, I too done a little bit of confusion:
http://mykenta.blogspot.com/2006/10/observer-subscriber-in-base.html
November 9th, 2006 at 6:30 am
Dustin,
I appreciate that as you wrap your mind around a concept, you share it with us. I also appreciate your slow methodical forward movement through JS and surrounding lines of thought. You take one small slice at a time, define the surrounding concepts, show us some code, explain the code, and give an example. Even if not 100% accurate 100% of the time, your willingness to share what is happening in your head is extremely helpful. I enjoy learning with you.
Thanks Mate,
Jim
November 9th, 2006 at 9:25 am
that’s funny, I wrote an extremely similar implementation yesterday into my project and there was a bug in the .fire, so I’m just going to integrate your .fire and be on my way :) plus your solution is a bit more elegant.
November 9th, 2006 at 10:45 am
@Jaydee: Soon enough. Don’t you fret.
@Bramus: Thanks man. Hopefully one day it will come as useful for you :)
@Cristian: Whether it completely follows the pattern strictly is one thing. However Think of it as s set of responsibilities by each side. Publishers “publish” new Observer subjects (or objects) for all observers to see. It’s better to think of these as Events in your application that listeners can subscribe to, and that they’re attached to some other meaningful object. Let’s pretend we’re dealing with Ajax.
The publisher is also responsible to notify the subscribers that their subject has gone through change (eg: that the event actually happened).
In the meantime, subscribers are the lucky ones who also truly benefit from this style of programming. When they’re ready to make a request, they can set their callback functions into the subscription:
@Jim: Always appreciate your feedback :) - and as a fellow YUI fan, it’s my duty to let you know that there is a much more polished version of Observer called CustomEvent which allows you to do a bit more things with data passing.
@Revoked: Glad it came just in time :)
November 9th, 2006 at 10:47 am
[...] Link [...]
November 9th, 2006 at 11:00 am
OK Dustin, is only because in my first implementation of this design-patterns I do
the same thing, but after a deeper look I understand that I haven’t understand the pattern.
In my point of view are both valid solutions.. depending on the circumstance..
Sorry for my english, I hope you understand what I want to said.
November 9th, 2006 at 11:29 am
Christian: Ours are both respectfully different means to the same goal. Both being slight variations of the pattern. UML can tell us one thing, but alternate designs can sometimes be more elegant. Beauty is in the eye of the beholder.
November 9th, 2006 at 12:32 pm
I actually like the event model for the observer/subscriber pattern in JavaScript. I did something similar a while back but modeled it after events: http://www.nczonline.net/archive/2004/11/61
I just think that implementing the strict observer/subscriber pattern as traditionally discussed is very error-prone in JavaScript. You’re assuming that the object in question has a property named onComplete (or another such name) that has a method call subscribe, so proper detection would involve looking for the object, then the observer property, then the method. On the other hand, just looking for addEventListener() requires only one step and, the part I like the most, if an event of the given name doesn’t exist, it fails quietly instead of throwing an error. :)
November 9th, 2006 at 1:03 pm
@Nicholas: I suppose it’s safe to say however, considering its size, that the developer will know about what methods they’ve inherited from the Observer object. You get subscribe and unsubscribe.
Taking perhaps the true approach to be more like the classic pattern is to extend the
Functionobject with subscribe and unsubscribe methods. Ala:In this case, your Observer object becomes the “observed” and takes the role of a host. And functions can subscribe to any given host. Eg:
November 9th, 2006 at 4:09 pm
RE: Cristian about the naming scheme
The actual naming scheme of methods is up to personal preference, it doesn’t have to follow a pattern exactly. There are other names for Observer such as Publish-Subscribe that are different in name only. I personally use subscribe/unsubscribe/publish when I write observers because to me, it is easier to pick up on what the actions actually do quickly.
On a side note, the naming scheme specified in the book Design Patterns (by Gamma/Helm/Johnson/Vlissides, a book I highly recommend) uses attach/detach/update.
November 10th, 2006 at 12:28 am
@Andy:
It’s not a question of Naming scheme,
what we were talking about is a difference in the implementation,
in one case the Observer raise the Event, in the other
is the Subscriber that raise the Event,
althought we both said that are both valid paths,
for me, and for Dustin is more natural to think that
Observer is the one who raise the event..
November 10th, 2006 at 12:48 am
[...] As a revisit to my previous post about making an Observer Class in JavaScript, I went ahead and built something new. You can call it “Observer Reloaded,” but I’m calling it “Publisher.” It holds a more truthful meaning to the original publish/subscribe model of the Observer Pattern. [...]
November 10th, 2006 at 12:57 am
@All: I would encourage you to also see the “Publisher” version that represents a similar idea and perhaps what Christian (kentaromiura) has been trying to explain. As I’m typing this, I can see that my trackback has already been posted in the comments directly above this one :) So Click on that.
November 11th, 2006 at 10:41 pm
Dustin,
Traditionally, the Observer pattern is applied to a class which needs to expose events (rather than as the event themselves). Your Observer class would be the event, the object being observed is the “Observable” (the publisher) and the subscriber would be the “Observer” (the one who listens). So the name could possibly use a little adjustment.
Anyway, this is minor. Great post.