Overview

This is one of the longer messages that JSLint reports. Here it is in full:

The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.

Here, JSLint is counselling you against making the assumption that the only object members ever found will be those that have been explicitly added to it (and not, say, to a base object).

For ‘Member’ In ‘Object’

Firstly, let’s recreate it:

var a = {b:1, c:2};
var x = 0;
for (x in a){
    alert(a[x]);
}

In the above code, we are creating a simple object using the object literal notation, and then iterating over its member. All seems well when we run it, as can be seen as this JSFiddle. So, what is the reason for JSLint’s complaint?

Here we are relying on the fact that elsewhere in our code base no-one will ever tinker with the underlying object, and add some unexpected properties or methods. Consider the following line of code:

Object.prototype.somefn = function(){};

Here, the prototype keyword allows us to extend the underlying object, effectively adding a new method somefn to every object in our system. Its effect can be seen in this JSFiddle – as well as the “1″ and “2″ alerts we also get the function definition alerted.

Clearly we want to filter out properties or methods that are not part of the immediate collection. But How?

We could extend out function to check for properties explicitly, like so:

function AlertAll(o){
    var x = 0;
    for (x in o){
        if (x === 'b' || x === 'c'){
            alert(o[x]);
        }
    }
}

(Also in this updated fiddle)

But this isn’t very scalable, of, for that matter, very  good! It introduces all sort of dependencies, coupling, technical debt, and other general bad words when it comes to programming. So how do we search for an objects own properties?

Easy! We check the hasOwnProperty property of the object, like so:

function AlertAll(o){
    var x = 0;
    for (x in o){
        if (o.hasOwnProperty(x)){
            alert(o[x]);
        }
    }
}

(Also in this further updated fiddle)

For ‘Element’ in ‘Array’

Done correctly, the for…in construct can be quite useful for iterating over object members (as shown in the above example). In JavaScript, every object has an equivalent array representation, so we can access the members using the array literal notation []. So, by logical extension, we can also use the for..in construct to iterate over a pure array.

This is madness inviting atrophy, as shown in the following code:

function AlertAll(arr){
    var x = 0;
    for (x in arr){
        alert(arr[x]);
    }
}
//We don't actually need to extend Array to show the ensuing atrophy
//Array.prototype.somefn = function(){};
var a = [0,1];
AlertAll(a);

If you don’t mind having to dismiss about 30 dialog boxes then feel free to see the problems at this JSFiddle. By examining the hasOwnProperty property as before we can, of course, solve this, but this is missing the point somewhat, which is “What is the point?”

We all (should?) know how to iterate over an array in JavaScript. We do it with a standard for loop like so:

function AlertAll(arr){
    var x = 0;
    for (x=0; x < arr.length; x++){
        alert(arr[x]);
    }
}

var a = [0,1];
AlertAll(a);

Provided for all its pointlessness at this updated JSFiddle.

Resouces

As always, a couple of resources from Stack Overflow:

Stack Overflow: What does the JSLint error ‘body of a for in should be wrapped in an if statement’ mean?

Stack Overflow: JavaScript: JSLint error “The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype”

A Guide To JSLint Messages

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

, , ,

JSLint flags any use of the eval statement with the message eval is evil. This is because eval is a hook right into the JavaScript compiler. It accepts a string as a parameter and then compiles it and runs it.

Further resources on the evils of eval are available through the above link. Here we are more interested in how document.write can equate to eval

So how can document.write possibly equate to being the same? Well, we can demonstrate this with a simple example. You’ll need to set up an HTML page and a JS File with the following code:

HTML File

<script src="a.js" type="text/javascript"></script>

JS File

document.write('<script type="text/javascript">alert(1 + 2);</script>');
alert(eval(1+2));

Or alternatively, download them from my sample: document.write.eval.zip

What happens when you run it? Well, you get “3″ output twice.

The JavaScript compiler picks up the first line, and writes out some more JavaScript, which itself has to be executed and fed back into a compiler. So, in effect, we have a line of JavaScript that is responsible for invoking the compiler again. This first line is sending 1+2 to the compiler to be evaluated.

This is pretty much identical to what is happening with eval(1+2) in our second line.

Of course, the above works because we have separated out our HTML and JS. What if we had it all in a single HTML page. Something like

<script src="a.js" type="text/javascript">
   document.write('<script type="text/javascript">alert(1 + 2);</script>');
</script>

When document.write outputs , it closes the original script tag on the first line. We are then left with a hanging ‘); that is output to the browser and an orphaned closing script tag.

This may not be eval, but it is certainly evil.

So, there we have it document.write can be a form of eval. But it doesn’t have to be eval to be evil. It should, therefore, be avoided.

We can, of course, turn this up simply by turning on the ‘evil’ JSLint option, like so:

/*jslint evil: true */

Thanks to the wisdom of StackOverflow for helping answering this: JSLint “document.write can be a form of eval” – How is this so?

A Guide To JSLint Messages

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

, , ,

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.

, , ,