On Javascript
This post is not accidentally timed with the recent flamefes^H^H^H^H^H^H^H^H healthy discussion on the PrtSc mailing list about languages -- the current round has been all about Ruby vs Python. I've seen my share of zealot wars over languages in the past. They never get anywhere, so I'm not trying to add to the fight. If you think discussing programming languages is productive, read Language Wars.
This post is timed with the PrtSc discussion, because it reminded me how great and unappreciated javascript is. As most current web developers, I tinkered with javascript when it was still Netscape's Livescript back in '95 or '96 (I don't really know the date and I'm too lazy to check out). I found a scripting language that looked a bit like C but was dinamically typed. It provided a very shallow learning curve, but otherwise unimpressive features: debugging was complicated to the point of painful, browser support was inconsistent and, lacking namespaces and source code inclusion, the language seemed fragile like a toy. I dismissed it for many years except for the ocasional form validation.
Then came Google, and Gmail, and suddenly ajax (javascript is eternally damned to poor names) was all the rage. I dismissed it as a feat only reachable by throwing hands at the problem in numbers only feasible by Google. I can't blame myself, having tried, and failed, in the past to develop something of an uniform toolkit for javascript use across major browsers.
Later on, I conceded to trying out dojo, jquery, prototype and scriptaculous. I must say that jquery and prototype were real eye openers. I was constantly wondering: "How in hell did they manage to pull that?". It turns out javascript has a couple of tricks I've never seen condensed in one language. And, yes, I missed them on the first pass over the language (I was 19 or 20, so I'm automatically excused):
It's Dynamic
Being dynamic just means that it is interpreted, which is usually a 'bad thing'(tm). It does, however, bring true platform independence, and eval. Eval, omnipresent in dynamic languages, brings lambda-function power to the language, so you have got functional language abilities in an OO language. I hadn't fully grasped the power of functional programming when I first used javascript, but you only have to look at Array.each on prototype for a real-world example.
Everything is an object
Not really true, but it will be soon. In javascript 1, everything but arithmetic types is an object. Javascript 2 corrects this fault, and turns everything into an object. I feel almost as cozy as in Smalltalk. Soon, I'll be writing arithmetic like 2->plus(2)->equals(5) (only to be beaten by RPN: 5 2 2 + =
). Remember, everything is an object. Even functions are objects. A function is an object with a call() method. When you call foo(), it's the same as calling foo.call(). You can add other methods (I'll later explain how) to the Function object, like the prototype folks did with bindAsEventListener. You can do foo.bindAsEventListener(form). Brilliant!
Dynamic binding
This is a braintwister for everyone starting on the language. The global object, this, is bound dynamically to the caller. You can have the exact same function, with the exact same function pointer, act as a procedural function or as a method on a myriad of objects. This is also why a constructor is a regular function, returning this, and invoked by new. Not exactly brilliant, not exactly indispensable, but a necessary construct for the mastermove:
Prototype-based inheritance
This is, for me, the crown jewel for javascript. As with all great ideas, it's easy to explain, and the possibilities reveal themselves when you digest the idea.
Inheritance (and polymorphism) in classical OO is handled by virtual function tables. When a function is called, a lookup is first executed on the virtual function table to find the real function address. These tables are created at compile-time. This is rather efficient, and is implementable at compile time, so it's an ok solution, and very popular.
However, javascript is a dynamic language. Static inheritance mechanisms don't need to be imposed. And they weren't. Javascript inheritance is dynamic and works like this:
- Every object has a prototype property. It points to the object's parent class (to an instance actually). It may be null for a top level object.
- Whenever a property is referred to, it is looked up in the object itself first. If not found, it is looked up in the object's prototype. This is, naturally, recursive.
Remember that functions are objects, so they are also properties (yup, braintwister).
This is all pretty magic, but it means that there is not a definite class hierarchy in javascript. You can graft methods to classes in a hierarchical fashion in order to produce a classical hierarchy. This is easily done on class constructors.
However, it is much much more powerful. You can change existing classes and objects by changing their prototypes. Prototype, the library, does it everywhere, like in document.getElementsByClassName.
And this is only the beginning. Think AOP is a novelty available in Java only? It's implementable in a couple of lines in Javascript. Just hijack the relevant methods, or the Function.call method, and there you have the hook points. With everything turning into an object, even accessor methods can be hijacked. Are you still discussing single- vs multiple-inheritance? Decide at runtime. You can even do mix'n'match inheritance, where you graft methods from a couple different objects, bound statically or dinamically, to create the exact object for solving a given problem.


Javascript is indeed a neglected but amazing programming language.
And this is only the beginning. Think AOP is a novelty available in Java only? It's implementable in a couple of lines in Javascript. Just hijack the relevant methods, or the Function.call method, and there you have the hook points. With everything turning into an object, even accessor methods can be hijacked. Are you still discussing single- vs multiple-inheritance? Decide at runtime. You can even do mix'n'match inheritance, where you graft methods from a couple different objects, bound statically or dinamically, to create the exact object for solving a given problem.
Do you know what's that called? Meta Programming. Ring a bell?
(Comment this)E Filman, DP Friedman - Workshop on Advanced Separation of Concerns, 2000
(Comment this)