My Biggest Peeves With JavaScript
Listen to this article
There's really not a lot to dislike about JavaScript; It's object oriented—in a way Java can only dream of; weak-typing coupled with dynamic property objects make mocking and testing a breeze; the list goes on. But there are two things about the language that continue to irritate me: Exceptions; and undefined/null. Ok, so I guess that's three things but the last two are really in the same category.
First up, undefined/null. Let me start by saying that I love the fact that these are actually objects—go null object pattern— but the fact that they silently gobble up any calls made to them is less than helpful. Even less helpful is the fact that I can't override this behaviour. Unlike every other object in the language, these two don't seem to have a prototype I can mess with. At least in Objective-C/Smalltalk you have the option of finding out when messages are sent to null objects or to objects that don't understand them. Thankfully, testing catches most of these problems but where it can't, I resort to my tried and tested method: runtime assertions. Which leads me to my second peeve.
Exceptions. Well at least JavaScript has them I guess, even if they are called Errors. Sure I can throw them, I can catch them, I can put code in a finally block but I can't get any information about them. I use runtime assertions all the time in Java, Objective-C and even JavaScript to catch things I haven't managed to test for or more importantly, things I can't necessarily predict. Whenever an assertion fails, an exception is thrown which usually dumps a stack trace giving me everything—well almost everything—I need to track down the source of the problem. Unfortunately in all web browsers I use regularly—Safari and Firefox—all I seem to get is the message "Error" printed to the JavaScript console. Great! So I know there is a problem but I don't know where, nor importantly why? This usually leads me to the JavaScript debugger—probably the best thing that ever happened to the language. Not that I mind using the debugger but a stack-trace is extremely useful!
Comments
Hah! My personal favourite would be arrays... adding numeric items to them changes their length, while adding non-numeric items doesn't - instead, they become properties of the array object. You can't get at them via the array syntax, but using item() works - unless you are using IE in which case the array syntax works also (and _really_ makes things confusing). Oh, and iterating the array only returns the numeric values, but iterating the items of the array returns the numeric and non-numeric values.
Throw in some test data which, _by coincidence_, is all numbers, and watch the fun begin.
Posted by: Robert Watkins | September 19, 2005 12:22 PM
Actually the array thing is interesting because Arrays are actually more like Maps (a.k.a. associative arrays) than the ones we're used to in Java. They just have "special" processing for numeric keys. Then of course there are methods like push and shift which make them more like stacks/queues. Egads!
Posted by: Simon Harris
|
September 19, 2005 01:18 PM
Um, no... arrays are real arrays. The problem is that _every_ Javascript object is an associative array of properties and functions. And arrays, of course, are Javascript objects, so they are also associative arrays of properties and functions, one such property being an array of values to which certain functions apply. The real bummer is that you can, under IE (which I was writing this Javascript for), use the same syntax for accessing the array as you do for the properties!
The extra special bonus funkiness being, of course, that Javascript doesn't have any types, so IE was inferring the "numericness" from the value, and doing different things with it. Fun stuff... I ended up ditching arrays for what I was trying to do and used a prototype object instead.
Of course, however, once you get past Javascript as a language, you then hit the inconsistent DOM models between different browsers (or are you using Javascript for non-browser work?). But you can't fairly put the DOM problem in the Javascript camp, as tempting as that may be. ;)
Posted by: Robert Watkins | September 19, 2005 10:55 PM
Hehehe...well that's what I was getting at: arrays are associative but with some funky behavior to handle integer keys. These are equivalent (thanks to weak-typing) assuming var a = new Array():
a[1] = "hello";
a["1"] = "hello";
In both cases a.length = 2 and a[0] = undefined.
Classes are really just a function--acting as the constructor--which--because it's also an object and all objects are associative arrays--has a list of properties, one of which is "prototype", the contents of which are used when constructing other objects.
It's all kinda weird but somehow I really like it, especially because it's all quite regular--assuming you understand what regular means ;-)
Posted by: Simon Harris
|
September 19, 2005 11:17 PM