I teach Ajax on a somewhat regular basis, so it’s rather embarrassing to admit I never really understood JavaScript closures. Of course, I thought I did. Now that I’m reading Dave Crane’s Ajax in Practice book, though, I see now what I was missing before.

He has wonderful examples in that book. I love it when he gives me examples that I can just type into a Firebug console in my browser and show everybody.

For example, I think one of the early samples is like:


function getName() {  return this.name; }

var o = new Object();
o.name = "Object";
o.getMyName = getName;

window.name = "Window";

getName();  // returns "Window"
o.getMyName();  // returns "Object"

In other words, the this variable points to the current window if you don’t say anything different, or to the current object if the method is a property of the object.

Then there’s the beauty of the call() function, which allows you to invoke a function in a particular context.


getName.call(o);  // returns "Object"

Sweet. Also, I get it now that there are no real classes in JavaScript. Instead, you have functions that act as constructors only because they have properties in them that get assigned. When you use the word new with one of these functions, you’re essentially creating a new Object and adding properties to it.


function MyClass() {
this.name = name;
}

MyClass.prototype.getName = function() { return this.name; }

var m = new MyClass("Fred");
m.getName();  // returns "Fred"
m.getName.call(window);  // returns "Window"

And the really weird part is that MyClass is just a function, so I could just call it directly without the word new. Also, the MyClass function has a function inside it, which returns another property of whatever the context object is.

Bizarre. As a developer who was raised on Java, it’s a whole different world.

I solemnly promise, however, that now that I’m really becoming a Groovy developer, I will not become one of literalists who claims that Groovy closures aren’t REAL closures. 🙂

4 thoughts on “OO JavaScript, such as it is

  1. This really isn’t a closure. This is what I call “object masquerading”, basically being able to provide a function with context. In your example, the context of the first is “window” and the context of the second is the instance you’ve created.

    A closure is a local variable that gets “sucked into” a function. The best example is something like: function(i){ return function(){ return i; }; }. This is where the local variable i from the outer function retains its value in the returned function.

  2. You’re right, of course. A “local” variable for window is really more of a global anyway, which I think is (part of) your point. I noticed in Crane’s book that in his classes he often creates a closure for a method handler by doing something like

    … in the constructor code …
    var instance = this;
    this.element.onclick = function() {
    // use the ‘instance’ var here
    }

    which he does because the “this” variable isn’t considered part of the closure, but the local variable “instance” is.

    It’s still a concept I’m getting used to, but I can see that understanding it really is a fundamental key to how JavaScript works.

  3. I downloaded and installed Firebug – cool.

    I entered you MyClass example and it failed. I believe the constructor code should be

    function MyClass(name) {
    this.name = name;
    }

  4. Ack. Of course. I forgot the entry in the function signature. I was typing code into the Firebug console in one window while copying it into another.

    Good catch. Thanks for the correction.

    Ken

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.