Improving the Module
Update: In my code example below, I make use of a self variable. This probably isn’t the best idea in hindsight since JavaScript reserves self as a secondary reference to window.
I’m always fascinated by the JavaScript language. What impressed me most, almost a year ago, was my discovery of Douglas Crockford’s module pattern. This was my first taste of what I consider to be the most intriguing thing in programming: closure. I didn’t understand the concept of closures when I first saw it, but after getting deeper and deeper into the language, it finally clicked. At that point I realized the potential of this type of language.
A few days ago, Peter posted his list of JavaScript warning words. To my surprise, “this” made the list.
Don’t get me wrong, I’m well aware of JavaScripts scoping issues, but it was still startling to see such a common element of my code sitting next to words like with, void, and eval.
He’s right though. If you’re not careful, “this” could quickly become problematic. For example, a constructor method declared without “new” would result in “this” being a reference to window and not the newly created object… oops.
This also becomes a problem when you use “this” in callbacks used for events. When methods are applied as event handlers, “this” generally refers to the element on which the event was applied — not the object that the function lives in when you write the code.
Peter advocates the use of closure as a means to reduce dependency on “this.” Today, I discovered an interesting pattern which does just that. Instead of relying on the ambiguous “this”, the following code creates a “self” variable in the module which is available in the inner functions as a replacement for “this”.
var mikeg = function () {
/* Create an internal reference to self as a replacement for this */
var self = {};
/* Return out self and some methods which have access to itself */
return self = {
SomeConstructor : function () {
console.log(window !== this);
console.log(self === mikeg);
},
someCallback : function () {
console.log(window !== this);
console.log(self === mikeg);
}
};
}();
It seems so obvious now that my fingers have found their way toward this code, but then again, isn’t that always the case? Looking back, I’m sure I’ve seen this elseware, but much like my original discovery of the Module, it didn’t click until after a little while.
3 Responses to Improving the Module
mikeg:
Unless I’m misunderstanding you, I believe you misunderstood me.
Closures are a concept whereby an inner function has access to variables set inside of an outer function — even after the outer function has executed.
In JavaScript, the immediate byproduct is private members.
Look at http://yuiblog.com/blog/2007/06/12/module-pattern/ for a much better description.
And you’re right, I do need to start playing with other languages. After reading the Pragmatic Programmer (see the book list), I’ve been committed going deep into a language per year. JavaScript was this year’s language.
MG
Sean Chambers:
On June 18th, 2008 at 10:39 am #
So bascially a closure in javascript == interface in most mainstream OO languages.
Although an interface has no implementation only a contract, so at the same time you are still tightly coupled to the methods since your client has knowledge of inner workings of the somCallback and SomeConstructor methods, your’re just coupled to a smaller surface area than you would if you were returning this.
Still pretty nifty though. Didn’t know you could do that in js
You NEED to start playing with some static languages. its time to be a small fish in a big pond instead of the other way around =)