Todd Ditchendorf advocates the benefits of anonymous classes:
While the XMLHttpRequest class is certainly a major step
forward for JavaScript in the browser, you have to
admit… this API is crap … Instead of passing a function
reference to [the XMLHttpRequest object], why not pass a
reference to a JavaScript object? … Notice how
[anonymous classes] allow you to package instance
properties (fields, variables, attributes, whatever) and
instance methods along with the actual callback method …
Sure … you don’t need this kind of functionality … you
can always just define a bunch of global functions and
global variables to be used by your callback function,
but, then you lose all the benefits that OO offers with
regard to combining state and behavior into a single,
encapsulated entity!
While I agree with his statements — the XMLHttpRequest API
is crap — the alternative to anonymous classes is not a
mess of global variables and functions, thanks to a
feature in Javascript known as closures. It seems many
Javascript developers don’t know about closures, as they
come from the functional, not object-oriented, line of
languages, so I thought I’d highlight them here.
Javascript allows functions to return functions, and I
think most Javascript developers will be familiar with
that. However, some may not know that such a function can
reference variables defined in it’s parent function, even
after the parent has returned. This means you can write
things like:
function makeSayHello(name) {
var sayHello = function() {
alert("Hello " + name);
}
return sayHello;
}
var noel = makeSayHello("Noel");
var matt = makeSayHello("Matt");
noel(); /* Says "Hello Noel" */
matt(); /* Says "Hello Matt" */
Notice that noel and matt refer to the
arguments to makeSayHello even
after makeSayHello has finished executing. This
is very useful when writing callbacks, as it allows you to
setup the callback with the parameters it needs avoiding a
mess of globals. For example:
function makeCallback(arg1 arg2) {
return function() {
doSomething(arg1);
doSomething(arg2);
}
}
You’ll see this pattern used a lot in our demos. It’s a neat trick and deserves to be better known.