JavaScript Tricks And Good Programming Style

Note that this is an updated version. Original version can be found here.

Thanks to the commenters I have updated this post with some better tricks.

In a loose series I'd like to point out a few of them. As I am currently mostly programming in JavaScript, I will write most of my samples in that language; also some of the tricks I mention only apply to JavaScript. But most of them apply to most programming languages around.

Optional parameter and default value #
When defining a function in PHP you can declare optional parameters by giving them a default value (something like function myfunc($optional = "default value") {}).

In JavaScript it works a bit differently:

var myfunc = function(optional) {
if (typeof optional == "undefined") {
optional = "default value";
}
alert(optional);
}

This is a clean method to do it. Basically I pretty much recommend the use of typeof operator.

update
Michael Geary (his comment) pointed out this solution that I like.


var myfunc = function(optional) {
if (optional === undefined) {
optional = "default value";
}
alert(optional);
}

The solutions mentioned (if (!optional), optional = optional || "default value", and the like) have problems when you pass 0 (zero) or null as an argument.

Commenters said that the 0/null problem is not one as this would not be the situation to use it. I would not say so. In an AJAX world where you do serialization back to a server/database often a 0/1 to false/true mapping has to be established. For default values it is important.

In case you just need to make sure that an object is not null I do prefer the mentioned

myobject = myobject || { animal: "dog" };

end update

Parameters Hints #
The larger your app gets, the more functions you get which you would use throughout the app. It also creates a problem with maintenance. As each function can contain multiple arguments it is not unlikely that you forget what those parameters were for (especially for boolean variables) or mix up their sequence (I am especially gifted for that).

So what I do is this: update substitute variables with comments end update

var myfunc2 = function(title, enable_notify) {
// [...]
}
myfunc2(/* title */ "test", /* enable_notify */ true);

This piece of code relies on the functionality of programming languages that the return value of an assignment is the assigned value. (This is something that you should also maintain in your app, for example with database storage calls, give the assignment value as a return value. It's minimal effort and you might be glad at some point that you did it).

If you do this you can see at any point in the code, what parameters the function takes. Of course this is not always useful, but especially for functions with many parameters it gets very useful.

Search JavaScript documentation #
When I need some documentation for JavaScript I use the mozilla development center (mdc). To quickly search for toLocaleString, I use Google: http://google.com/search?q=toLocaleString+mdc

As I am a German speaker I also use the excellent (though a bit out-dated) JavaScript section SelfHTML. I use the downloaded version on my own computer for even faster access.

The self variable #

update
… should be avoided. Even if someone like Douglas Crockford (creator of JSON) uses it and calls it that.

Let me quote Jack Slocum who put it best:

// used to fix "this" prob with Function.apply to give call proper scope
// nice method to put in your lib
function delegate(instance, method) {
return function() {
return method.apply(instance, arguments);
}
}

function Animal(name) {
this.name = name;
this.hello = function() {
alert("hello " + this.name);
}
}

var dog = new Animal("Jake");
var button = {
onclick : delegate(dog, dog.hello)
};
button.onclick();

I removed my code as it can be considered obsolete by this.
end update

Reduce indentation amount #

update
I have removed the code because it leads people into believing something different than I meant. So let me put it differently:

What I am opposing is white space deserts. If you have many levels of indentation then probably something is wrong.

If a for loop only applies to a handful of cases, don't indent the whole loop in an if clause but rather catch the other cases at the top.
Often it is advisable to move longer functionality to a function (there is a good reason for that name) that you call throughout a loop.
end update

That's all for now, to be continued. Further readings on this blog:

update
Eventhough some commenters disagreed with what I said, I think posts like this are very much needed in the bloggersphere. Even if they are not free of errors on the first take, great people can help improve them. I would appreciate if more people took that risk.
end update

, ,

JavaScript Tricks And Good Programming Style – Original Version

Note that there is an updated version

I have been programming for about 10 years now, and I am always longing for improving my code. Throughout time I added a few habbits that I consider to be good practices and increase the quality of my code.

In a loose series I'd like to point out a few of them. As I am currently mostly programming in JavaScript, I will write most of my samples in that language; also some of the tricks I mention only apply to JavaScript. But most of them apply to most programming languages around.

Optional parameter and default value #
When defining a function in PHP you can declare optional parameters by giving them a default value (something like function myfunc($optional = "default value") {}).

In JavaScript it works a bit differently:

var myfunc = function(optional) {
if (typeof optional == "undefined") {
optional = "default value";
}
alert(optional);
}

This is a clean method to do it. Basically I pretty much recommend the use of typeof operator. Some people would do the above with a if (!optional), but my version works cross browser (e.g. Safari will throw an error when you try to negate null).

Parameters Hints #
The larger your app gets, the more functions you get which you would use throughout the app. It also creates a problem with maintenance. As each function can contain multiple arguments it is not unlikely that you forget what those parameters were for (especially for boolean variables) or mix up their sequence (I am especially gifted for that).

So what I do is this:

var myfunc2 = function(title, enable_notify) {
// [...]
}
myfunc2(title = "test", enable_notify = true);

This piece of code relies on the functionality of programming languages that the return value of an assignment is the assigned value. (This is something that you should also maintain in your app, for example with database storage calls, give the assignment value as a return value. It's minimal effort and you might be glad at some point that you did it).

If you do this you can see at any point in the code, what parameters the function takes. Of course this is not always useful, but especially for functions with many parameters it gets very useful.

Also be careful that you would override the variable names in the scope of which you are calling the function. You might mini-namespace the variables, e.g. with letter+underscore (p_title, p_enable_notify).

Search JavaScript documentation #
When I need some documentation for JavaScript I use the mozilla development center (mdc). To quickly search for toLocaleString, I use Google: http://google.com/search?q=toLocaleString+mdc

As I am a German speaker I also use the excellent (though a bit out-dated) JavaScript section SelfHTML. I use the downloaded version on my own computer for even faster access.

The self variable #
This technique comes from Private Members in JavaScript by Douglas Crockford. By assigning a value in a function to this.value it will be publically accessible afterwards.

function Animal(name) {
this.name = name;
var self = this;
this.hello = function() {
alert("hello " + self.name);
//alert("hello " + this.name); // would fail
}
}
var dog = new Animal("Jake");
button = {
onclick = dog.hello;
}
button.onclick();

The cause of this problem is that the this keyword receives different values in different contexts. See here for a closer explanation.

Problem with this solution is that I am not absolutely sure if this creates a memory leak in internet explorer

Reduce indentation amount #
One of the most annoying things I find in other people's code is this: (multiple) nested if clauses. Something like this:

var arr = ["dog", "cat"];
var action = 'greet';
for(i = 0, ln = arr.length; i < ln; i++) { animal = arr[i]; if (animal == "cat") { alert("hello " + animal); } }

This is only a short example, but I often saw this going deep into 10 levels of nested clauses. I suggest using the break and continue (and next in Perl):

var arr = ["dog", "cat"];
for(i = 0, ln = arr.length; i < ln; i++) { animal = arr[i]; if (animal != "cat") continue; alert("hello " + animal); }

This accomplishes the same with only one level of indentation. One more example for a function:

function greet_animal(animal) {
if (typeof animal == "undefined") return;
if (animal != "cat") return;
alert("hello " + animal);
}

Javascript is one of the few languages where you can leave the return value empty (i.e. typeof greet_animal() == "undefined"). You might want to rather use return false so that you can easily determine if the function failed for some reason.

, ,

Unknown Blummy Treasures

Steve Rubel re-mentions blummy on his blog. Thanks a lot!

I'd like to take this chance to show you some of the lesser known blummlets (or bookmarklets if you prefer). Take a look at how I have configured my blummy.

blummy: alexa

Alexa

The favorite of my blummlets (and in this case it deserves to be called like that, as it is an image), is the Alexa blummlet on the bottom. I just have to open blummy on any page on the web and I can instantly see how much traffic it has (well as far as you can count on Alexa on that).

When you add the blummlet you might want to resize it to fit yours. So first add it to your blummy, then resize the blummlet by holding shift and drag from within that blummlet. Voilá.

Click2Zap

blummy: click2zap

Click2Zap by Steve Clay (site is currently down) is something for you if you print web pages a lot. I dislike reading long texts on-screen (waiting for the Sony PRS-500), I print blog texts a lot.

Using click2zap you can remove unnecessary text or links from a web page before you print it. You can click on a paragraph, a red dotted border will appear. You click again, it's deleted. Very neat.

BlummyWiki

What Google Notebook has added to Firefox, has been possible through Blummy for a long time. Cross-browser.

blummywiki: google notebook

When you surf around you can use the BlummyWiki to store information you find on a page for later use. Or maintain a list of your most often visited pages. Most useful thing about it is that can use the same blummy account on multiple browsers and multiple computers.

Andy Roberts already had some ideas what to do with the BlummyWiki. Check it out.

, , , , ,