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.

, , ,

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.

, , , ,

JSLint reports this error when a function name has been omitted from a functions statement. For example:

function(a) {
    alert(a);
}

It is possible that the original intention was more like the following:

function foo(a) {
    alert(a);
}

Although, it is also conceivable that a function expression was also intended:

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

A Guide To JSLint Messages

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

, , , ,

This message was acutally too long for the subject title. In full, it reads:

“Function statements should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.”

We can reproduce this message with the folllowing code:

var a = 0;
if (a === 0) {
    function b() {
        alert(1);
    }
} else {
    function b(a) {
        alert(2);
    }
}
b(); //call the function. But which one?

The intention is to decalre a function based on some condition, but this doesn’t necessarily work, and the condition is likely to be ignored. Instead we are at the mercy of each inditidual implementation of the JavaScript interpreter.  With the above examples, we may see either “1″ or “2″ alerted.

To achieve what we are attempting we need to use a function expression, like so:

var a = 0;
var b;
if (a === 0) {
    b = function() {
        alert(1);
    }
} else {
    b = function(a) {
        alert(2);
    }
}
b(); //call the function.

This will work every time.

A Guide To JSLint Messages

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

, , , ,

With this message we move deep into the heart of JavaScript closures. Without wanting to engage into a discussion about what they or their relative merits are, we can examine how this message might arise. Take the following code:

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

The parentheses around the function are necessary, because when omitted, the compiler assumes it is a Function Statement (see links below).

When referring to ‘Invocation’ we actually mean the bit of code (a) at the very end of the block of code. Although the code itself will execute perfectly, JSLint prefers that everything is more self-contained, so insists on the following convention instead:

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

This is almost identical, except the invocation (a) now appears within the parentheses that wrap the function.

The most convincing for me is that the initial parentheses isolates the block of code that is being invoked by the second set of parentheses. In addition to this, JSLint has been designed specifically to eliminate conventions and behaviours that have been proven to lead to bugs and issues, so it is possible that sometime in the past the first convention has yielded a bug or some sort of issue.

Some Links

For more information on closures, refer to Closures in JavaScript by James Padolsey.

The above function code follows a convention more commonly known as the JavaScript Module Pattern

To demystify the mire of Function Declarations, Function Expressions and Function Statements, refer the article Named function expressions demystified by Juriy “kangax” Zaytsev.

Also thanks to StackOverflow for helping me answer this: Question –  Solution for JSLint Errors

A Guide To JSLint Messages

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

, , , , , ,

JSLint has very specific constraints about how you use new. This message is displayed when JSLint encounters an object that has been constructed using new Array() instead of simply = [].

In JavaScript we can declare a new array as follows:

    var a = [];
    var a = new Array();

This example is innocuous – they both achieve the same effect – an empty array. But what if we want to add some initialisation?

    var a = [5];  //new array one in size contaning the value 5
    var a = new Array(5);   //new array five in size, each item 'undefined'.
    var a = new Array('5');   //new array one in size containing the value '5'

Well, here our problems start, as the comments indicate. The first declaration initialises an array with a single value ’5′, whereas the second declaration initialises an array of five ‘undefined’ values. The third declaration, however operates differently to its immediate predecessor, initialising an array with a single value ’5”.

While they all might be what is intended use of new Array() is subject to inconsistency and confusion. In addition to this, once constructed, we have to do a subsequent assignment to add new values. Using the literal notation we can perform the assignment upon declaration.

Furthermore to this, the Array keyword could also be overridden:

    Array = {};
    new Array(); // TypeError: Array is not a constructor

Whoops! Of course, I would question the wisdom of overriding ‘Array’, but nevertheless, using the array literal notation would help us steer clear of this problematic scenario.

Special thanks to the respondents of Stackoverflow for helping me write this article – Stackoverflow Question – JSLint: “Use the array literal notation []” for var os_map = {}.

A Guide To JSLint Messages

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

, , , ,

JavaScript functions can be written as a declaration or as expression, as in the following examples:

function a(){} //function declaration
var a = function(){};  //function expression

The first line declares a function, and the second declares a variable. For the purposes of this discussion, we can think of the key word ‘function’ as having a similar purpose to the keyword ‘var’, namely, that it declares something (‘a’ in both cases).

Both are perfectly legitimate ways of declaring a function, as is the following:

var a = function(){alert("1";)};
a = function(){alert("2");};

All we are doing here is reassigning the variable ‘a’ with a different function expression. JSLint will not complain about this in the slightest, simply because there is nothing wrong with this. However, what if we substitute the first line above with a function declaration, JSLint starts complaining with ‘a’ is a function:

function a(){alert("1";)}; //JSLint error: 'a' is a function
a = function(){alert("2");};

Instead of ‘a’ being a ‘var’, it is a ‘function’, but in the second statement we attempt to use it as a ‘var’. In other words we are attempting to turn it from a function declaration to a  function expression.

You may find out that the interpreter is tolerant of this, but it is still indicative of something potentially problematic, and possibly not what was intended.

For more information on function declarations and function expressions, refer to this article at JavaScript, JavaScript. Related, and also of interest is this article on JavaScript Scoping and Hoisting.

A Guide To JSLint Messages

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

, , ,