Isolating your code with closures

When writing unobtrusive javascript code one technique often used to isolate code from the rest of the scripts on the page is creating and immediately executing an anonymous function, like this:

function() {
  // Code to isolate may be put in here
  function sayHello() {
    alert("Hello World!");
  }

  window.greet = function() {
    sayHello();
  };
}();

// You can use greet here, but not sayHello
greet(); // Alerts "Hello World!"

Here is the twist. Because function greet was explicitly assigned to the window object (which represents the global scope), we may call it even after the anonymous function has finished. It is available in the global scope. But we can’t reach function sayHello. It effectively has become private. The cool thing is that function greet can still reach sayHello so it can now make use of private helper functions without those functions being exposed to the outside world. They are isolated.

The reason this works is that the anonymous function creates a new scope, so any variables and functions declared in it are isolated from the other code on the page. It encloses all functions and variables inside it and they remain available even after the function terminates. This principle is called a closure and it forms the foundation of Packages JS, my package management project.

You can read more about closures (including some excellent and very technical analysis of how and why it works) on the JavascriptWeblog article
Understanding JavaScript Closures.

DOMContentLoaded is finally here!

DOMContentWhat?

DOMContentLoaded. It’s an event like the (on)load event that fires once an HTML document has finished loading, but it is tons more useful than the good old load. You see the problem with the load event is that it fires after the complete page has finished loading, including any embedded resources such as images. This is usually not what we actually want in Javascript, because it will make our scripts wait for the last image to load before coming into action, making our page seem slower than it could be.

What we want instead is for our script to fire as soon as the HTML document itself has finished loading, but before all the images have actually loaded. We just want to make sure the DOM is complete so we can safely manipulate it.

Enter DOMContentLoaded.

Browser support

DOMContentLoaded was first introduced by Mozilla and slowly has gathered more following. It was implemented by Opera and Webkit (which also means Safari and Google Chrome), so it was supported by all browsers except of course Internet Explorer. So we had this very useful event but couldn’t rely on it because the browser with the largest market share did not support it. But that has finally changed! And we have HTML 5 to thank for it!

Standardization

As part of the HTML 5 effort the W3C is standardizing the DOMContentLoaded event and other actions that the browser is supposed to perform when it reaches the end of the HTML document in section 8.2.6 of the HTML 5 specification. And because Internet Explorer 9 is betting heavily on supporting HTML 5, they have implemented DOMContentLoaded! You can test drive it here.

Supporting old browsers

So there you have it. DOMContentLoaded is now supported by all major browsers. It will of course still take some time before the old browsers have disappeared from the scene so we will still have to support fallback code for some time to come. For that reason Packages JS, my personal stab at a modular Javascript framework, comes with a version of the famous addEvent and removeEvent functions in the package dom.event that transparently support DOMCOntentLoaded on old and new browsers alike, always giving the best possible result for the browser the script is actually running on. But that’s for another post.

OSGI for Javascript

We recently started working with OSGI (1) in our project and it’s petty nice. It’s a system for managing dependencies at runtime, enabling deploying and undeploying modules at runtime, with modules (‘bundles’ in OSGI terminology) automatically being stopped when a module it depends on goes away for some reason, and restarted when it comes back. Not too big or complex, just a small framework that gets the job done. Actually OSGI is a specification and the framework is an open source implementation of it called Apache Felix (2).

We develop in Eclipse and recently I stumbled upon an article about Eclipse E4, the soon to be fourth incarnation of the Eclipse IDE.

What was interesting about it is that the Eclipse people are looking at projects like Firefox with very succesfull add-on systems and are aspiring to implement the same ability to be able to write plugins in Javascript. Traditionally Eclipse plugins are written in Java and deployed as OSGI bundles, but OSGI is not available for javascript. Javascript doesn’t even have packages and namespaces, let alone bundles. But the cool thing about javascript is that you can bend it to your will. So they implemented javascript namespaces in the same way the people of Dojo (3) did and on top of that created a system that will let you write OSGI bundles in javascript. How cool is that? This kind of clear dependency management is what’s needed to scale javascript powered web applications to the extent that they can rival desktop applications.

(1) http://www.osgi.org
(2) http://felix.apache.org/site/index.html
(3) http://www.dojotoolkit.org

Is Prototype evil?

Let me begin this critique by saying that I think Prototype JS is an inspired piece of work and that it inspired me to think about javascript in a whole different way. It’s also a stable framework that gets the job done and is used on a large number of websites. And it’s very comfortable programming when you know prototype is on the page, because it offers a lot of nice and handy feautures which are not natively available cross-browser.

So it must be good right?

Well… here’s where my story begins about what I don’t like about Prototype JS. But first, take a look at the source code for prototype 1.6.0. You don’t have to read it all, just glance at it and scroll through the file a bit. That’s a lot of code right?

This blog is about unobtrusive javascript… but I really can’t call prototype unobtrusive due to the sheer size of it. If unobtrusive code should not get in your way, how can a mammoth like prototype qualify?

Don’t get me wrong here. I don’t really care about the size of the file. I care about the size of the codebase. The number of objects and methods that it exposes and I thus should know about. Because unobtrusive javascript is about not getting in each other’s way. It’s about working together with other scripts on the page. By having a rather large API, with a fair amount of short identifiers in the global namespace, other scripts sort of have to ‘know’ that prototype is on the page and adjust for it. Just read about the dollar function clash between jQuery and Prototype JS.

But that’s not all of it. Just having a large API does not make prototype evil. But prototype is monolithic. It’s not a large set of modules in one file, though it may look like that. It may even be stored like that in CVS. But it’s not.

Some pieces of code may be worse than others, but the pieces of code that I have personally tried to pull out of prototype were very interwoven with the rest of prototype.

For example prototype tends to ‘enhance’ DOM objects and arrays using functions $() and $A(). Those functions then add some extra methods to otherwise native types. Those enhanced methods are happily called everywhere, but they are prototype specific.

Then there is the Prototype object that contains a load of useful properties and functions. Those are used throughout the code. Very convenient, but it makes all that code dependent on that object. A lot of times, the offending line of code could easily be replaced by an only marginally longer line of code that avoided the dependency.

The same goes for a lot of functions that prototype adds to native objects. Such as Object.isFunction(), which just returns typeof object == “function”. Ok so your checks become a teeny bit shorter and more readable. But it makes your code dependent on a function that is only available in prototype. It’s the spirit of coding that prototype was built with: no duplicate code. That’s good to some degree, but if it comes at the expense of modularity, I choose modularity. It’s the old story of tight cohesion, loose coupling. Prototype is tightly cohesive as a whole. I think they should have separated the code more into modules and introduce loose coupling between the modules. As it stands now, it’s monolithic.

And this monolithicness seems to be contageous. Code gets infected by it. Hey if you want to use function A from prototype, you need to include all of it, so you get function B for free as well. And since it’s there.. why not use it, right? And then, if your code is useful, why not include it right into prototype? This way, the framework never stops growing…

Prototype viral? Well that may be pushing it, but just read this article about pimping some code for inclusion into prototype that I think illustrates what I’m saying here, and draw your own conclusions.

I told you prototype inspired me. It was inspiring to see how much you can bend javascript to perform the way you want it. And when I realized it was monolithic, it inspired me to create a solution: Modular javascript with Packages JS.

I’ve given up on trying to make protoype modular. It’s just too interwoven for me to get any joy out of doing that. So instead I’m trying to build up my own personal framework of scripts I like using Packages JS. Give it a try!