HTML5 Crash Course: Digging into Javascript’s Weirdness

HTML5 Crash Course: Digging into Javascript’s Weirdness

[snip-h5cc]

Today I looked at the HTML5 Boilerplate and KnockoutJS.

  • HTML5 Boilerplate is an application framework, meaning it’s a bare-bones way of structuring the way your HTML5 app loads resources and starts up. The alternative is to come up with your own organization.

  • KnockoutJS is a pure Javascript library that implements a “Model – View – ViewModel” pattern in a clean, declarative way. I don’t yet know exactly what the ramifications are, but there’s an awesome interactive tutorial that walks you through it.

<

p>Exploring these two environments today gave me additional insight into Javascript Weirdness related to its super-flexible object-oriented underpinnings. Basically everything is an object, even the ones that look like they might be functions or expressions. Writing Javascript is like living on the frontier, where STREET JUSTICE prevails over centralized language specification. There are no police. It’s up to you to enforce good programming habits, because Javascript doesn’t have any built-in to save you from shooting yourself in the foot.

As a result, you need to explore the Javascript community for a bit to understand what the law of the land is. Here’s some of the ones that I collected yesterday:

Functions and Parenthesis

The jQuery library is used everywhere, as it is one of those libraries that makes cross-browser DOM manipulation more “write-once” than “hope and pray it works in every browser”, which was the reason I avoided Javascript for so many years. To start executing your code that uses jQuery, though, you need to make sure it’s loaded. Since browsers load resources asynchronously, and also have slightly different ways they do it, jQuery itself provides a means to call your important startup function: $(document).ready(). The ready() call takes a function as an argument, which is executed when it’s time to run.

Unfortunately, in the non-trivial code examples, the ready() sometimes looks like this:

(function($) { 
    $(function() {
        // code using $ as alias to jQuery
    });
})(jQuery);

Note the enclosing parenthesis. WHAT IS THIS? The short answer is that it converts the function() definition into an object expression which is then executed immediately, with the jQuery object passed to it as a parameter. WHY IN THE WORLD would you want to do something as convoluted as this? It’s to make the variables in your code private through the implicit creation of a Javascript “Closure”, which is the variable scope/state within a function. Since scripts in a browser all run in the same global namespace, they can overwrite each other. The code here creates an anonymous function, which in turn has its own closure with the $ variable assigned to the jQuery object. Everything inside has its own private space to declare whatever variables it wishes. Furthermore, the variable state exists after the code finishes running (another aspect of closures which is a bit different from other compiled languages), so you can safely assign event handler functions that refer to variables inside; they remain persistent.

The enclosing parenthesis is not necessary, but is added so you can tell right away that this is the case. Technically, Javascript will do the closure thing because of the (jQuery) tacked on the end, but it is unclear that it’s not a function definition until the very end. Adding the explicit () around it turns it into an explicit EXPRESSION instead of a function declaration; this is pure coding style because the () at the end also turns the function declaration syntax into an expression, but you see it all the way at the end and then you’re like, “damn, this isn’t a definition that’s called, it’s something that runs right now”.

You also see stuff like:

!function($) { 
    $(function() {
        // code using $ as alias to jQuery
    });
}(jQuery);

I KNOW…WHAT? The ! is the unary negation operator, and it has the side effect of telling Javascript that an expression follows it. This is the same effect as using (), which is the arithmetic precedence operator. Both, being operators, turn the function into an expression, which is OK because expressions can be executed when a () is after them to turn it into a function invocation. That executes immediately. You could also use + or – as well and get the same effects…it’s purely for code readability.

It seems stupid, but it’s necessary to establish a private namespace (via closures) so you can write code without side effects like name collisions. Other languages have explicit ways of establishing a namespace, but Javascript does not.

Well, there is stuff like this:

var myNameSpace = myNameSpace || {}
myNameSpace.myProperty = 1;
myNameSpace.myFunction = function(x) {};

This creates an object with objects assigned on-the-fly. Although since I used var, it’s local to the closure that the namespace is declared in. If I didn’t use var, I think that means it would be in the global namespace. Argh.

Anyway, that is enough of this for the day. Here’s the links that helped me understand this:

  • http://michaux.ca/articles/an-important-pair-of-parens
  • http://blog.themeforest.net/tutorials/ask-jw-decoding-self-invoking-anonymous-functions/
  • http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

0 Comments