JS Coding style

2010-07-25

This is my coding style for writing JavaScript. For certain aspects I have good reasons, others just grew over time for no apparent reason. In general I like to write compact code. That means single lining where possible and not breaking at 80 characters. Other than that I try to be clear about my intentions.

Of course, always indent code. This goes without saying and I won't even give an example. I personally prefer tabs of 2 spaces, because that makes navigation easier.

I don't care about and never take into account the 80 character wrap boundary. With 22" screens I really think it's time to move on. The exception is sometimes comments, but I wrap them at arbitrary lengths, whatever feels nice.

I always try to add semi colons, including when assigning functions. I don't doubt their requirement one bit for JavaScript. You may be as ninja as they come, you can still trip over not using semi's. I feel it's a must and seeing production code that misses semi's hurts me. Really!

I always put the opening curly on the same line as the control flow that starts it. Always with a space between the closing parenthesis and the curly brace, except for anonymous functions (even when assigned to a variable), where I leave out the space. This last exception is something that I've grown accustomed to, maybe it signifies that it's an unnamed function. I'm not sure. The closing curly is aligned with the indentation of the control to which the block belongs.

Code: (JS)
var x;
for (..) {
..;
..;
}
function hello(..) {
..;
}
var f = function(){

};
while (..) {
for (..) {
..;
}
}

I use a single line for an if when I can. If not possible, or it doesn't match the style of a larger if-then-else block, I'll put it on two lines with curlies. Never do I put a single line if on two lines without curlies. And I absolutely hate it when I see that, in any language.

When a control statement has a lot of (long) conditions and I feel the line becomes to long, I wrap it, indenting the next line one tab beyond indentation of the previous line. From the top of my head, I don't really have a solid method for putting && and ||, but whichever way I pick I do it consistently (always before or after). I sometimes tend to add a tautology at the beginning so I can safely put the || and && before all conditions (one condition per line). With tautology I mean true in case of && and false in case of ||. The closing parenthesis of the control statement will be aligned with the control statement. I don't really like to create multi-line conditions for control statements though so I try to avoid them (but sometimes..).

Side note; If I multi line an SQL statement and it has multiple conditions I always add the tautology and start with the AND or OR, followed by the condition.

Code: (JS)
if (true
&& ...
&& ...
(false
|| ...
|| ...
)
&& ...
&& ...
) {
...;
}

if (...) ...;

while (...) {
...;
}

The if-then-else group are either put on single lines, or from starting at the first condition that uses curly braces I'll use curlies for the rest as well, even if they could be single lined. In that case the single line else clause may not get the curlies, but that depends on the context I guess.

I put the closing curly of the previous block on the same line as the else, immediately followed by the curly. Something I've adapted not so long ago, but have grown to like very much.

Code: (JS)
if (..) ..;
else if (..) ..;
else if (..) ..;
else ..;

if (..) ..;
else if (..) ..;
else if (..) {
..;
} else if (..) {
..;
} else {
..;
}

Let's see, what else. Oh var. To be honest, I can be sloppy with var statements. Ideally I will declare them all as the first statement of a new context, using one var statement. If there are a few I'll single line them, but with more or when they require some clarification I'll multi line them, giving each additional line an extra tab compared to the var statement. The comma will be at the end of a line (but before the single line comment, if any), not at the beginning. I don't like that. For multi line var statements, the name of the first var will occur on the second line, not the same line as "var".

Code: (JS)
var a,b,c;
var a=5, b=6, c=function(){ ...; };
var
a=5, // ...
b=6, // more ...
c=function(){ ...; },
d=function(..){
...;
...;
},
e=b; // see what I did there? and it's perfectly valid

To be honest, especially in small and quick projects, I don't tend to group var statements. I know, shame on me. And in that case I almost always use a single statement per var. Partially because I know it won't matter anyways. I don't really like to declare new variables inside control flow, but do sometimes anyways (laziness). This strongly depends on the target of the code though. If it will be shared with other people, I'll always try to group them, to prevent people getting confused if they don't know about hoisting.

Functions... I'll single line them if they contain a single statement (or sometimes two or three short ones, depending on context). Otherwise I'll multi line them, where the closing curly will be aligned with the line that has the function keyword that started it. For anonymous functions, part of an argument list or chain, if they spread multiple lines the closing parenthesis that wraps it will be put right after the closing curly.

Code: (JS)
function name(..) { ..; }
var x = function(..){ ..; }
var x = function(..){
..;
..;
};
var
x=5,
y=function(){ ..; },
z=function(){
..;
},
xyz;
abc.go().read(function(){

}).book(function(){ ..; });

Chaining is an interesting case for JavaScript. I guess the major debate (for as far as it's major ;)) is whether the dot operator goes at the beginning or the end of each line. I tend to put them at the front, while not indenting the line any further. The dot signifies the chaining, which serves as the indentation as far as I'm concerned. I'll usually chain single line, except when one of the arguments is multi line or when the single line would become to long.

When the argument of a chain is multi line I either put the next chain on a new line, or continue single line style after the closing parenthesis. I know, not very consistent. Shame. Again.

Code: (JS)
a.b().c().d(function(){
..;
})
.e()
.h(function(){

}).f().g();

Object and array literals are either single lined or multi lined, depending on context, item count and length. In case of multi line, I indent the next lines one tab compared to the initial line. The first element will appear on the second line.

In the case of objects I'll do a special thing if the context allows for it. If it's an object I'll be modifying a lot I'll add a placeholder element at the end so I can safely add a comma after the last real item. This prevents problems in IE, which doesn't allow this style (thank god it's been added to ES5, but unfortunately that won't fix the IE case for a while). I use the underscore for that, which I've taken from Haskell where the underscore signifies a placeholder. I sometimes use an underscore for function parameters as well, if I know the parameter will be passed on but not used. I'll have to be careful in ES5 strict, where two of those will b0rk ;) When I use the placeholder key for an object, I add it on the same line as the closing curly (!). I guess it helps hiding the unused item.

I almost never quote my object key names in literals, except when I use key names that really require it (and I hardly ever use such keys). It's useless cruft that annoys me.

Depending on the length of the contents, I tend to add a space (for single line) after each comma for clarity.

Code: (JS)
var arr = [1,2,3];
var arr = ["hello", "world"];
var arr = [
1,
2,
3
];
var obj = {a:b, c:d, e:e}; // note that e:e is perfectly fine :)
var obj = {
a:b,
c:d,
e:e,
_:0}; // the _ key will show up when enumerating! but if you don't enumerate the object it allows you to add keys and don't worry about the comma suffix. this style is obsolete for ES5, of course.

Comments. I actually tend to write a lot of comments. Probably too much. But I hate it when I can't remember my line of thought for a program I wrote two years ago.

When writing code I will share (work, project or website) I will always try to add formal JSdoc style function headers. I don't usually care about the other header comments (file, class, whatever). I'll use @param and @return and sometimes some of the other gazillion tags.

For @param I actually tend to use an order I've learned in PHP: @param string name rest-of-comment, although I don't really like it. I'm planning on taking over the JSdoc notation, which seems to switch the type-value pair order.

I either write the type of a parameter in formal class (ie. the capitalized version), or the lowercase version. Not very consistent as I'm still trying to figure out which of the two feels better. On the one hand String seems appropriate, on the other hand I actually mean string because it's an primitive, not an object. Then again, an object would also be string. I guess Javascript is a little weird in this matter.

The opening of a jsdoc is /**. Every next line starts indented and gets an additional extra space (to align the stars), another space and then content starts. The actual comment starts on the second line. Each token (@param, @return) will be on their own line and I seldomly break them up. If I pass on an object with certain keys, I'll prefix them by a dash after the @param line, one line per option.

The actual comment can be wrapped but I don't have a static length for it. Whatever feels good at the time of writing.

Code: (JSdoc)
/**
* This is a function that
* does bla.
* @param string a ...
* @param string|number c ...
* @param int|mixed=50 ...
* @return bool|string
*/
var f = function(){
};

// I seldomly annotate variables I create
// although I'm working on it :)
// and I never use multi line comments when I
// want to write multi line comments that are
// not in the header. I use a series of single
// line comments for that. Wrapping them as I
// see fit. (This also allows you to wrap the
// whole thing in a multi line comment, if you
// ever want to disable a block of code).

I can be a little inconsistent with spaces between parameters or assignments. I'll be consistent for some area, but can even be inconsistent throughout a script. Although I think I prefer spacing the arguments but not the assignments...

Code: (JS)
function x(a, b, d){}
function x(a,b,d){}

For loops have the same setup when using a single variable. For multiple variables it depends on my mood, but usually as short as possible while still adding one space after the comma. I'll always add one space after the semi-colon though. I hardly ever use for loops more sophisticated than this (yes, I know I could, but what's the point).

Code: (JS)
for (var i=0; i<5; ++i){}
for (var i=0, n=arr.length; i<n; ++i){}

And then there are switches. I never use the default case before another clause. That's just weird. I always try not to fall through, but will sometimes violate that rule. I will indent all cases and all code that follows from them. If a case can be single lined (ex break), I will do so, adding the break to maintain the single line. If not, the first line of code goes on the next line from the case, getting one extra level of indentation.

The only place where this is a little screwy is the default case, because it doesn't jump back and there's always two levels of indentation between the default case and the curly that closes the switch. I always hate to look at that :(

Code: (JS)
switch (x) {
case "a": ++i; break;
case "b": return 5;
case "c":
++i;
return 5;
default:
fault = true;
throw Error;
}

For creating new constructors and classes there are two styles I've adopted. I usually start out with explicitly declaring each prototype object separately. After a while I might notice I have a lot of declarations and refactor them to an object literal. I like the object notation style, but somehow I always start with the separate prototype declarations.

Code: (JS)
var Fu = function(){};
Fu.prototype.f = function(){};
Fu.prototype.g = function(){};

Fu.prototype = {
f: function(){},
g: function(){},
_:0};

For try-catch I'll use the same style as if-then-else, except for one case. If the try block has only one line, I tend to put it on the same line as the try keyword. In most cases this allows for a double lined try-catch (unless the catch block is multi line, of course). I think I actually don't put a space between catch and the opening parenthesis, which is a little weird. Maybe it's because the catch also creates a new scope, like function? I'm not sure :)

Code: (JS)
try {
..;
..;
} catch(e) {
..;
..;
}

try { ..;
} catch(e) { ..; }

try { ..;
} catch(e) {
..;
..;
}

While we're on JavaScript style, let's talk naming conventions. I always use as much lower case characters as possible, obviously in a camelcase fashion. Only constructors and singletons start with an upper case character. Furthermore constants are all upper cased, using underscores for spaces. Variables almost never get underscores. I don't use the underscore prefix for private methods.

I'll virtually always camelcase abbreviations as well, leaving only the first character upper cased. The only weird exception here seems to be my CDE library, where I consistently put all letters either upper or lower case. Weird.

A year ago I learned to program using variables that are prefixed with their type (Systems Hungarian notation, the long version). While very verbose, it helps in a project where multiple people work on the same code. I must admit that I don't really use this in personal code, except sometimes when I try to be formal. I adopted the style that prefixed up to three or four letters of the type. Could never get used to the single char version for some reason.

Ohwell, I guess that's all for now. I wonder what I'll think about this in a year from now, or two, or five.

Hope it helps you, probably not :p