I’ve been working with JavaScript for years. It was my replacement for a server side language when I couldn’t afford to buy web space in the mid-90’s. Still, as the language becomes popular again, I recognized that I did understand the basics but there was much more to the language.
So I dug into the topic a little deeper. I can highly recommend reading the blogs of all the great JavaScript guys like Alex Russell (of Dojo), Aaron Boodman, Erik Arvidsson (both at Google), Douglas Crockford (at Yahoo). (Give me more in the comments ;)
So, JavaScript is easy to start with. You can take a procedural approach like in C. You declare a function
, you call a function.
A Survey of the JavaScript Programming Language (by Douglas Crockford) does an amazing job at explaining the notable aspects of the language on a quite short page.
I want to point out the most interesting points for me:
Subscript and dot notation
You can access a member of an object by using two different notations:
var y = { p: 1 };
alert(y["p"]); // subscript notation
alert(y.p); // dot notation
The great difference is that with subscript notation you can also access member vars that contain reserved words (of which there quite a few in JavaScript). Dot notation is shorter and more convenient.
Different meanings of the this
keyword
Consider this piece of code creating a small object.
click here
<script type="text/javascript">
var myobject = {
id: 'obj',
method: function() {
alert(this.id);
}
};
myobject.method();
var l = document.getElementById("link");
l.onclick = myobject.method;
</script>
When you call myobject.method();
, this
points to the current object and you receive an alert box with the text ‘obj’. But there are exceptions:
If you call this function from within a HTML page via an onclick
event, this
is refers to the calling object (i.e. the link). You will therefore receive and alert box containing ‘link’ as message.
This can be useful in many cases, but if you want to access “your” object, you can’t. Aaron Boodman proposed a function that was eventually named hitch:
function hitch(obj, meth) {
return function() { return obj[meth].apply(obj, arguments); }
}
You’d use it like this: l.onclick=hitch(myobject, 'method');
Now the this
keyword points at the correct object.
You could also change the function to something like this and still use the previous notation:
method = function() {
if (this != myobject) { return myobject.method(arguments); }
alert(this.id);
}
Creating objects with new
I was always wondering how to create objects from a class as I am used to with other programming languages, which means that by instanciating the object is created according to the “building instructions” of a class.
Douglas shows this in more detail on his Private Members in JavaScript page.
I’ve quickly hacked together this example:
var x = function () {
var created = new Date();
this.when = function () { alert(created); }
}
var p, u = new x();
window.setTimeout("n()", 1000);
function n () {
p = new x();
p.when();
u.when();
alert(typeof p.created);
}
You receive 2 objects p and u that have different creation times. They also have a private variable created which is only accessible via the public function when (because specified via this).
So even as you create an object by using the new Object() or {} notation, you only receive a static object. If you want to instanciate it, you need to create it as function.
Closures
The example above already demonstrated closures. The fact that closures exist in JavaScript make it only possible to create private variables.
A closure is, to put it simply, a function within another function. The inner function has access to it’s parents variables but not the other way round.
All together a function is just another data type that can be assigned to a variable. Therefore these two notations can be used interchangably:
function test() { alert(new Date()); }
var test = function() { alert(new Date()); }
The ominous prototype “object” is a way of using the this keyword from “outside”.
Modifying the piece of code from before:
var x = function () {
var created = new Date();
}
x.prototype.when = function () { alert(created); }
But there’s a pitfall. The created variable is private. Even though the function when now is a member of the object x it does not “see” the variable created. So in the original example the function when had privileged access (see Private Members in JavaScript).
Concluding
All in all I see that JavaScript is a powerful language. Many things that can be accomplished in an elegant (and sometimes quite unusual) way. (Curried JavaScript demonstrates even how to use it as a functional programming language)
I realize that there is a nice and clean solution for almost every problem you come across. This is where libraries come into play. The downside: you can quickly add tons of libraries, leading to large page sizes and memory consumption.
dojo for example is a really great library that provides you with numerous well thought-out functions, making your life a lot easier. But the size is 132 KB, just for the basic functions. More than a mega byte all in all. It circumvents needing to load everything by an in time loading mechanism (dojo.require).
In my opinion we’d need something like a local library storage. A Firefox extension would be a nice first step.
As far as I have looked into that topic, though, there are some difficulties. Foremost there is a problem with namespaces. Firefox clearly separates JS code by extensions from those coming from the web. A good thing, security-wise, but hindering in this case.
Maybe some Firefox guru can tell a way how to circumvent this, I think it might be worth a shot.