Notice This is a beta feature offered by Google. Also this is automatic translation, which means the results are often inacurate and/or hilarious. Enjoy.

ARCHIVES / RSS
Blog

JavaScript variables: get a brain! morans

h3  ~  9 Jan 2008, 19:16  –  12 comments

The things that probably bugs me the most when I read somebody's JavaScript is bad variable naming practices.

If your variables looks something like MyLib_someContext_variableName it's ugly and hard to read.

There is good chances that you did so to avoid variable name collision with other's code But the truth is that you don't have to namespace your variable with underscores to keep things clean.

Let's take jQuery's thickbox for example, if the author would have enclosed is code in a anonymous function, like jQuery does, he would not have to prefix every variables (and functions) with TB_.

But beyond ugliness, using the global namespace is something that you want to avoid at all costs, even more when writing libraries, it's a one way ticket for hell and somebody will eventually blog on how bad your code is.

1. Variable naming

Let's take a very simple example with the thickbox's coding style versus mine (or jQuery).

TB_W = 0;

Now let's hope that there isn't any other library that use a variable named TB_W !

(function(){

	var w = 0;

})();

* Edit:* I forgot the var :/

It's safer because the variable is not accessible from other scopes, cleaner and requires less code (ok not in this useless example obviously).

If I'd wanted this variable to be accessible form the outside I would do this;

(function(){

	var w = 0;

	jQuery.extend({
		w: function(val) {
			if (val) return w = val;
			else return w;
		}
	});

})();

How cute is that. Of course the function is optional.

2. Multiple variables declarations

This one is debatable, but in my opinion it's a good practice.

TB_W = 0;
TB_H = 0;
TB_X = 0;
TB_Y = 0;

If you actually read the code, it says; Variable TB_W equal zero, Variable TB_H equal zero, Variable TB_X equal zero, Variable TB_Y equal zero

I'd rather say; Variables w, h, x, y equals zero.

w , h , x , y ;

It's a lot more intuitive, compact and faster. End of debate.

*Edit:* Thanks to whoadave, the previous syntax is invalid, this is the right one:

w = 0, h = 0, x = 0, y = 0;

// Edit: or as a commenter pointed out

w =  h = x = y = 0;

3. Namespace

I don't think that underscores should be avoided in variables names, although I try to because I find them inelegant. But using them to emulate namespace isn't good.

If you really want some a namespace in your variables use an object:

var coordinates = {w:0, h:0, x:0, y:0};

alert(coordinate.w + 'x'+ coordinate.h);

4. Quotes

This is probably obsessive, but I loose hairs every time I see something like this:

html += "<a href='"+url+"' title='"+title+"'>"+ caption + "</a>";
html += caption;
html += "";

Three things:

  • string concatenation is slow, array join is faster
  • JAVASCRIPT: SINGLE QUOTES
  • HTML: DOUBLE QUOTES... KTHXBYE

html = ['<a href="',href,'" title="',title,'">',caption,'</a>'].join('');

Of course, there is a better way with jQuery:

html = $('<a></a>').attr(href:href, title:title).text(caption);

OK, enough for today..

PS: I hope no one will be offended by my title, it's really just a joke. Beside.. that guy on the picture is so funny, I had to use it somewhere :D

post a comment Comments

> w, h, x, y = 0;

Umm, I think you meant: w = 0, h = 0, x = 0, y = 0;

whoadave ~ January 9, 2008 at 7:59 p.m.

Nice trick about the whole (function(){...})() thing...I hadn't heard of that before but it's pretty powerful.

Eric Florenzano ~ January 9, 2008 at 8:35 p.m.

Damn ! you're right whaodave.. thanks

My bad.

h3 ~ January 9, 2008 at 8:42 p.m.

In #1 above, the w variable inside the anonymous function is still a global. Change that to "var w = 0;" and then it's local.

Anonymous ~ January 9, 2008 at 9:05 p.m.

You're scoping code isn't quite correct. try this:

<code class="javascript"> (function(){ w = "Scoped?"; })(); alert(w); // Shows "Scoped?". </code>

You need to add a "var" declaration to indicate that it's a local variable:

<code class="javascript"> (function(){ var w = "Scoped?"; })(); alert(w); // Error: w is undefined </code>

Nathan ~ January 9, 2008 at 9:15 p.m.

w = x = h = y = 0;

The above also works and is shorter. Some might consider it obfuscated, but it works for me.

Joshua Paine ~ January 9, 2008 at 9:19 p.m.

If you want short, valid, syntax, it's:

w = h = x = y = 0;

Anonymous ~ January 9, 2008 at 9:29 p.m.

Sorry to say it but despite your best effort, your code is worse than the Thickbox stuff. Significally worse!

First rule of javascript programming, always use var when declaring a variable. If you do not, you declare a global.

eg:

<code class="javascript"> (function(){ w = 0; })(); alert(w); // dialog with 0 in it </code>

compared to:

<code class="javascript"> (function(){ var x = 0; })(); alert(x); // error, x undefined </code>

Andrew ~ January 9, 2008 at 9:35 p.m.

Seriously Andrew, just because I forgot the var ?

It's fixed now, give me a break.

h3 ~ January 9, 2008 at 10 p.m.

first of all, your idea of placing all your code in a function invocation -- including all your functions -- is horrible since it means every function will close the outer function, so you'll get all the nasty memory leaks in IE6 because of it, and your lookup chain will become longer (like when you use with{}) so your code will go slower. that is, you will have to do:

local -&gt; closed outer func -&gt; global

rather than

local -&gt; global

whenever you need to disambiguate a global reference.

the best way to avoid polluting the global name space is to use an object oriented prototype based style, with member variables on your objects and static variables on your classes, and then just place all your classes into an object which represents the package, so there is only 1 name being added to the global space. for example:

acme.MyClass = function(){};
acme.MyClass.myStaticVariable = &quot;Hi&quot;;
acme.MyClass.prototype.myMethod = function(){
    this.myMemberVariable = &quot;Hello&quot;;
};

you see, the only thing polluting the global space now is the acme package, and there will be one of those for your entire application/library.

oh, array joining is not faster than + (it's slower), its only faster than +=, or it's longhand x = x +, and this is for ie only. so, a faster and neater way to write that code would be:

html = &quot;&lt;a href=&#39;&quot;+url+&quot;&#39; title=&#39;&quot;+title+&quot;&#39;&gt;&quot;+ caption + &quot;&lt;/a&gt;&quot; + caption;

if that is all we were going to do, or:

aHtml.push(&quot;&lt;a href=&#39;&quot;+url+&quot;&#39; title=&#39;&quot;+title+&quot;&#39;&gt;&quot;+ caption + &quot;&lt;/a&gt;&quot; caption);
// more html code
var sHtml = aHtml.join(&quot;&quot;);
dominic ~ January 9, 2008 at 10:16 p.m.

Thanks for the insight dominic, there is some useful informations.

but FYI it's not my idea, jQuery use this paradigm for quite a longer than me, they deserve more credit than me for it.

And well.. I can live with the fact that it might be "a bit" slower in IE6, time will fix it.

h3 ~ January 9, 2008 at 10:30 p.m.

There is another advantage to using a function to scope the variables -- variable look up can improve in performance. In the global scope it is much more difficult to determine variable location, locally scoped variables however can be reduced to an indexed lookup, thus making local var lookup much easier. To an extent this same optimisation can be applied to globals, but only at the global scope -- accessing a global property in a function scope requires multiple hashes as you walk up the scope chain.

Incidentally (directed at dominic), using 'with' is a plague. The first thing that happens in a with block is that JS starts lying:

<code class="javascript"> var x = true; with (o) { var x = false; } alert(x); // what is the output? </code>

The second is that it kills performance -- inside a with block you have adding a completely dynamic object to the scope chain, so it is no longer possible to do any form of fast variable lookup.

Oliver ~ January 9, 2008 at 10:54 p.m.
Copyrighted stuff .. u know.