And just what is “this”?

I’ve just spent about three hours debugging JavaScript. If you’ve never debugged JavaScript yourself, let me assure you, it’s a real pain. Rejoice that your life, whatever its disappointments, has not led you to this pass. If you have, and you know my pain, let me share some hard-won insight and advice. For instance, “this” may not mean what you think it means.

I admit I was asking for it when I decided to transform the bowl of spaghetti scripts I had coded so far for my fancy Web 2.0 application into something nicely abstracted and encapsulated, that is to say, when I decided to go Object-Oriented. When writing object-oriented Javascript:

  1. Use Firebug. I can’t believe I ever used to debug with only “alert” commands. The most common error in JS occurs when some variable is undefined and your script fails, silently as death. Use Firebug to step through your code and discover that you misspelled a variable in line 147, and that’s why your page is totally blank.
  2. Mind your scope. I’ve started using Prototype, which extends core JS objects with lots of commonsensical functions and features. I love it. However, now that I’m employing these wonderful new features, I’m using a lot of anonymous functions, which is new to my JS programming. I keep making the same mistake with the keyword ‘this‘. Once you’re inside an anonymous function, e.g. as an iterator for an each() loop inside a class method, ‘this’ doesn’t refer to the putative instance of the object. Nor does ‘this’ correspond to the item in the collection you’re looping through. No, ‘this’ now refers to the global window object. (Thank you, Firebug.) To show you what I mean:

Browser.prototype.activate = function(special_item) {
this.item_array.each( // ‘this’ refers to Browser instance. O.K.
function(item) {
if (item.id == special.id) {
item.current_state = “on”;
writeCookie(this.cookie_search_name, item.id); // Now ‘this’ won’t work

You can use the Function class’s bind() function to manage the identity of this, but I’m finding that isn’t necessary.

So, I’m slowly and painfully improving. At the very least, Firebug is making it more interesting to read through my code to find the typo that’s held me up for half an hour.

Still, I wish there were a way to make Javascript warn you when you try to use an undefined variable as an object. Something like Perl’s strict pragma would save everyone a lot of grief.