Why Bother?

JSLint contains a number of messages pertaining to the style, appearance and formatting of JavaScript code. This includes stipulations about bracing positions, indentation and spacing.

As a demonstration of this paste the following into http://jslint.com/

var x = 0;
switch(x){
    case 1:
        x++;
        break;
    case 2:
        x--;
        break;
    default:
        break;
}

Zero errors, right? Now click the flag ‘Strict white space’ (‘white’) and recheck…

Yikes! 10 errors (at the time of writing)!

So why should JSLint possibly care what your code looks like? After all, it’s all about bugs, isn’t it?

Well, on the surface, legible code equates to more maintainable code, which itself equates less ambiguity and fewer bugs. But you may have your own internal guidelines that dictate how the JavaScript looks, i.e. how you indent, where you put your braces, etc. So you will have probably flipped the ‘white’ flag to ‘off’. After all, when given the above code snippet, JSLint returns a substantial amount of what you consider to be ‘noise’, which if no use to you. Right?

However in turning this option off, you are missing the opportunity to have a uniform and consistent convention across your code base, and a tool that can tell you where you are deviating from it.

But sometimes, formatting and positioning does have functional implication as well, and can lead itself to bugs. Consider the following code:

function GetObjectLiteral()
{
    return
   {
       x:0,
       y:1
   };
}
alert(GetObjectLiteral().x); //what do you expect?

Regardless of what you expect the above to return, what you will not get is an alert box with the text ’0′. Different browsers may behave differently. IE8 complains about a missing semi-colon, whilst others will simply execute the ‘return’, passing control back to the calling function, and then fail to find the member ‘a’

Changing the bracing position fixes the code:

function GetObjectLiteral(){
    return{
       x:0,
       y:1
   };
}
alert(GetObjectLiteral().x); //alerts '0'

The Messages

So, let’s have a look at some of these messages…

Expected ‘{a}’ at column {b}, not column {c}.

This is a simple case of incorrect indentation. The most basic demonstration of this can be seen in following code snippet:

var a = 0;
  var b = 0; //Problem at line 2 character 3: Expected 'var' at column 1, not column 3

Expected ‘{a}’ to have an indentation of {b} instead of {c}.

This is another indentation catch. The default indentation step is 4, meaning that indentation columns should start at positions 1, 5, 9, 13, 17, etc. The sample below uses an indent of 5 spaces, placing the start of the new column at character 6 (as the message denotes).

function MyFunc() {
     alert("hello"); //Problem at line 2 character 6: Expected 'alert' at column 5, not column 6.
//3456789
}

Expected exactly one space between ‘{a}’ and ‘{b}’.

This message goes some way to supporting JSLint’s assertion of correct bracing positions. You will see this message generated on the following code snippet.

if (x === 0)
{  //brace on next line
    alert("hello");
}

But even when you do place the brace on the correct line, JSLint requires you to apply the correct spacing. So, the following code snippets will also yield this message:

if (x === 0){ //no spaces
    alert("hello");
}

if (x === 0)  {//two spaces
    alert("hello");
}

Missing space between ‘{a}’ and ‘{b}’.

Haveyoutriedreadingsentencesthathavetheirspacesomitted? Generally, it’s not that easy, is it?

if (x === 0){    //Missing space between ')' and '{'
    alert("hello");
}

Mixed spaces and tabs.

This message is displayed when a line is indented with a mixture of spaces and tabs. Most IDEs will have an option to convert tabs into spaces automatically. I suggest you turn this on.

Unexpected space between ‘{a}’ and ‘{b}’

Here, JSLint is reporting that you have included a space where it did not expect one. The following code snippet will yield this message:

if ( x === 0){  //Unexpected space between '(' and 'x'
    alert("hello");
}

A Guide To JSLint Messages

This article is one of a series on the error and warning messages produced by JSLint.

, , ,

JSlint may just occasionally save you from yourself.

The following code is clearly nonsense. The clause will never evaluate to true, and your alert will never be shown:

if (1 === 0) {
    alert("hello");
}

But you’ll also get the JSLint message where the clause does evaluate to true:

if (1 === 1) {
    alert("hello");
}

In general, this message will appear when both sides of the clause are literal values or if they are identical, for example:

if (myVar === myVar) {
    alert("hello");
}

We are not just limited to ‘if’ clauses, either. ‘while’ tests will also yield this error.

A Guide To JSLint Messages

This article is one of a series on the error and warning messages produced by JSLint.

, ,

In a JavaScript ‘switch’ block, JSLint expects every ‘case’ statement to be broken with a ‘default’ keyword.

So, the following code sample will fail:

var x = 0;
switch(x){
    case 1:
        x++;
        //where's the 'break;'?
        //so, 'fall through'
    case 2:
        x--;
        break;
    default:
        break;
}

In this sample, after evaluating ‘true’ for ‘case 1′ and executing the adjacent code, the interpreter will ‘fallthrough‘ to the next clause and test that. In the above code the next clause will evaluate false, so there is not a problem.

Many consider this an advantageous language feature. Consider the scenario where you want to execute the same code under two different circumstances (i.e. implement an ‘or’ equivalent). For example:

var x = 0;
switch(x){
    case 1: //fallthrough
    case 2:
        x--;
        break;
    default:
        break;
}

Douglas Crockford, however considers this to be a little too tricky. In his book ‘JavaScript: the good parts’, he mentions this:

I want to avoid idioms that look like mistakes.

I never allow switch cases to fall through to the next case. I once found a bug in my code caused by an unintended fall though…

He goes on to explain that language features that are sometimes useful, but occasionally dangerous are probably best avoided as it can be difficult for a developer/reviewer/maintainer to differentiate its use from a bug.

A Guide To JSLint Messages

This article is one of a series on the error and warning messages produced by JSLint.

, ,

This one is fairly self-explanatory, so I’m not going to waste too much time on it.

In short, your switch statements really ought to have a ‘case’ statement. Otherwise they are really just pointless, empty blocks. Take the following:

var x = 0;
switch(x){
    default:
        break;
}

It’s hardly surprising that JSLint is going to complain about this.

The ‘why’ here should be obvious. Clearly you have some redundant code that should be removed or have omitted a chunk for functionality.

A Guide To JSLint Messages

This article is one of a series on the error and warning messages produced by JSLint.

, ,

JavaScript isn’t very particular about whether or not you declare your variables (its loosely typed). In fact, you can often get away without doing so. Consider the following:

x = 0;
alert(x);  //alerts '0' quite happily

The about example isn’t overly problematic, but that doesn’t mean that its a sensible thing to do. This, assumes you intended to do this. Consider the following:

var receivedParts = 0;
recievedParts = GetReceivedParts();

Whoops! Can you spot what’s wrong? Yes, we’ve spelled ‘received’ differently (mixed the ‘e’ and ‘i’ in our typing). JavaScript doesn’t care, though.A value is assigned to the latter without complaint.

Of course we might have intended to do this, but even this is inadvisable. Consider the following:

receivedParts = receivedParts + 1;

Our variable isn’t defined, so, again we have a bug.

Of course, in strongly typed languages, this isn’t an issue. In effect, JSLint is attempting to make JavaScript a more strongly typed language.

A Guide To JSLint Messages

This article is one of a series on the error and warning messages produced by JSLint.

, , ,

JavaScript will let you repeat your declarations without complaint, however it’s rarely, if ever, a good idea to do so:

var x = 0;
var x = 1; //no complaints!

JavaScript here will simply disregard the first declaration. The above is clearly nonsense, but there are circumstances in which a developer might declare a variable twice in faith. Consider the following:

if (condition) {
    var x = 0;
} else {
    var x = 1;
}

Here, the developer has made the assumption that JavaScript allows you to scope variables locally. The developer is, of course, wrong in this assumption. All declarations are hoisted to the top of the containing scope. So, in effect we still have two declarations.

The same message is produced for other declarations, e.g. functions:

function foo(){};
function foo(){}; //'foo' is already defined.

Multiple declarations of the same name are subject to confusion and buggy code, and therefore should be avoided.

A Guide To JSLint Messages

This article is one of a series on the error and warning messages produced by JSLint.

, , ,

In JavaScript we can assign a function expression to a variable, like so:

var foo = function() {
    return 1;
}; //assign function expression to 'foo'

This is perfectly valid, and often useful.

It is also possible to assign a variable the return value of the function expression by invoking the function, like so:

var foo = (function() {
    return 1;
}()); //assign '1' to 'foo'

This is also valid, although less commonly useful.

These are two distinct techniques with distinct conventions, so, the following may well give rise to confusion:

var foo = (function() {
    return 1;
});//assign function expression to 'foo'

The above is equivalent to the first sample of code, and will execute in exactly the same way. JSLint encourages you to wrap invoked function expressions with parentheses. Wrapping non-invoked function expressions in the same way may be indicative of something non-intentional, or at very least be misinterpreted by a future developer.

In other words, stick to the first convention for the assignment of function expressions.

A Guide To JSLint Messages

This article is one of a series on the error and warning messages produced by JSLint.

, , , ,

This is the longest error message that JSLint boasts. In full it reads:

“Wrap an immediate function invocation in parentheses to assist the reader in understanding that the expression is the result of a function, and not the function itself.”

What a mouthful!

This is relatively simple to explain, however:

var a = 1 + function() { return 1; }(); //assigns '2' to the variable 'a'

The JSLint error can be addressed by adding parentheses around the function:

var a = 1 + (function() { return 1; })(); //assigns '2' to the variable 'a'

However, this will yield another JSLint message Move the invocation into the parens that contain the function.

So, of course to address this, we wrap the whole invocation with the parentheses, like so:

var a = 1 + (function() { return 1; }()); //assigns '2' to the variable 'a'

So what is the reason for this? Well, actually, the message itself explains is quite well: “Assist the reader in understanding that the expression is the result of a function, and not the function itself.” Not all of JSLint is about bugs and problems. Some are all about achieving a consistent style. This is one of them.

This is similar to another wordy JavaScript message: Function statements are not invocable. Wrap the whole function invocation in parens, which captures isolated unwrapped function declarations. Seen in the following example:

var a = 0;
function foo(a) {
    alert(a);
} (a);

Here, we can see that, again, the invocation is missing a wrapping parentheses. However, in direct contrast to the first example, the code immediately above will fail.

A Guide To JSLint Messages

This article is one of a series on the error and warning messages produced by JSLint.

, , , ,