Sep 22nd 2008 08:43 pm

Understanding the Javascript language from a .Net based background

Ever wonder why the Microsoft samples for Ajax always call Function.createDelegate? Why IE6 has such bad memory leak problems? Ever wonder what “this” in javascript refers to?

Javacript is dynamic and interpreted.  Superficially this means that:

  • all objects have a dictionary of properties. One can then modify this dictionary in a very tangible if not intuitive sense by simply setting properties on the object.
    var x = [];
    x.someProperty = 1;
  • the dictionary of properties can be enumerated like a collection
    for (var property in object) {..}
  • arrays are really just objects with properties, the “key” in the dictionary is the array index
    var x = {0:”test”} ;
    is the same as
    x = ["test"];
  • one can use the “eval” statement to translate and execute any string of code
    var p;
    eval(“p=1″);
    will set p equal to one.

There are, however, some more basic questions whose answer is not quite obvious such as:

  • how does one implement inheritance?
  • what does “this” refer to?
  • what is the difference between calling a shared method and an instance method? How does one denote one versus the other?
  • how do I bind an html element’s event to an event handler method on my object?
  • how do I bind an object event to an event handler method on another object?

Most developers assume that Javascript is merely the scripting equivalent of java, but that is not so. To quote Douglas Crockford (JavaScript Architect at Yahoo!):

JavaScript’s C-like syntax, including curly braces and the clunky for statement, makes it appear to be an ordinary procedural language. This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java. It has arrays instead of lists and objects instead of property lists. Functions are first class. It has closures. You get lambdas without having to balance all those parens.

Coming from a .net background, I really don’t remember much about Lisp from college – I remember lists, lots of parentheses, and thinking “It’s all about recursion”. One key feature of Javascript is the closure. To quote wikipedia:

a closure is a function that is evaluated in an environment containing one or more bound variables. When called, the function can access these variables.

A good explanation with examples can be found here. In javascript one can still create object oriented code with private and public methods. It is not, however, intuitive to do so. Opposite from .net, standard class methods are public and accessible as static members. Closures are what gives us state in our methods by binding variables to objects when the method is executed, particularly the “this” object based on context.

In ASP.Net, one adds an event handler like so:
textBox.TextChanged += new EventHandler(SomeObject.TextChangedHandler);

In order for this to work, “SomeObject” must be instantiated and the TextChanged event bound to “SomeObject”. 

Suppose instead that I could create a new method like so:

textBox.TextChanged += new Function(sender,eventArgs=>some other code)

In this case I don’t need to initialize an object or create a static method to handle the TextChanged event. Instead I create an anonymous function and databind the sender and eventArgs parameters to the caller and the caller’s event args.

This is exactly what Javascript has been doing since IE5. The coding emphasis is now on the function to handle the event using databound variables rather than forcing the developer to go through hoops to instantiate objects and wire up methods on those objects. The mechanism that lets you do this is the closure.

Closures lead to certain issues, however, specifically the funarg problem.  Simplify stated a closure may contain a reference to almost any object on the heap. The garbage collector now has to determine if an object is referenced by any closures before destruction. The amount of additional work reqiured for reference counting and object graph traversal is monstrous.

The garbage collection algorithm used by IE6 has been notorious for leaking memory due to poor garbage collection. In November 2007, Microsoft finally recognized the problem and released a partial fix. Microsoft notes here that:

New Web applications live up to higher standards. A page might run for hours without being navigated and retrieve updated information dynamically through Web services. Language features are pushed to the breaking point by combining complex event schemes, object-oriented JScript, and closures to produce entire applications. With these and other changes, certain memory leak patterns are becoming more prominent, especially those previously hidden by navigation.

The good news is that memory leak patterns can be easily spotted if you know what to look for. Most of the troublesome patterns you might face have known workarounds requiring only a small amount of extra work on your behalf. While some pages might still fall prey to small memory leaks, the most noticeable ones can be easily removed….

Closures are a specific form of circular reference that pose the largest pattern to existing Web application architectures. Closures are easy to spot because they rely on a specific language keyword and can be searched for generically

If Javascript is more like scheme or Lisp than Java, then perhaps just learning a new syntax isn’t enough to properly code Javascript. Take a moment and check out Douglas Crockford’s site, particularly his javascript tutorial and javascript history. The more you learn about Javascript, the more you will realize how vastly different it is from any Microsoft technology prior to .net 3.5.  You’ll also get a much better idea how the language constructs of .net 3.5 (lambda expressions, closures, extensions, etc.) are revolutionary in bringing some of the power and flexibility of dynamic languages into static ones without sacrificing compile time type checking and performance.

What is easy and clean in javascript (using the prototype library):

originalList.findAll(function(p) {
  return p.Age > 50;
})

Is now just as easy in .net 3.5:

results = origionaList.Where(p=>p.Age > 50).ToList();

If you’re working on a javascript heavy application, take the time to learn about the language and to lever its inherent features rather than try and bend it to a static language paradigm.

1 Comment »

One Response to “Understanding the Javascript language from a .Net based background”

  1. andrew on 05 Oct 2008 at 9:07 am #

    This is a great article on closures for .net programmers. There are some great points in this article, specifically the emphasis on event binding and memory management, and of course the great explanation of a closure. It’s still hard for me to wrap my head around the idea of closures, or some of the really weird scenarios they can conjure up. You’re always saying that you need to know the language “one level deeper”, having the more intimate knowledge allows you to make the amazing cross language analogies, this is what REALLY helps me understand the ideas. This is a great article and i’ll be forcing anyone coming onto our team to read it!

Trackback URI | Comments RSS

Leave a Reply

« | »