JSLint prompts you with this message when it encounters what it perceives to be a dangerous, or “bad” assignment. For example:

document.getElementById("text"+x) = function(){};

In the above code, we are calling a function, and then attempting to assign it a value. Clearly the case of document.getElementById() nonsense anyway, and will fail. It doesn’t shed any light as to how this sort of error might occur, so let us look an example with custom objects.

It is possible to create a function within a JavaScript object in many ways. The following demonstrates one such scenario:

var obj = { fn : function () {}};

No problems here. But what if we wanted an ad-hoc creation (possibly as part of some sort of desire to extend an existing object)? We might see something resembling the following:

var obj2 = {};
obj2.fn = function () {};

Again, no problem. However it is conceivable that we might encounter the following (entered, perhaps, by accident):

var obj2 = {};
obj2.fn() = function () {};

Do you spot the subtle difference? The developer has stipulated an extra set of brackets. It will certainly not what was intended, but has found its way into the code. When JSLint encounters this, will complain about a bad assignment.

But, in JavaScript, object members can also be referenced using the array/collection [] notation. Happily, JSLint is clever enough to spot this. So the following will yield the same error (along with another JSLint error [{a}] is better written in dot notation):

document["getElementById"]("test") = function(){};

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 declare a function anonymously, and using a concept known as late-binding we can attach the event to an HTML object:

document.getElementById("control").onclick = function(){//code};

We can also conceive a situation whereby we can do this to multiple controls within a loop. Casting aside the capabilities of JavaScript libraries such as jQuery for the moment (we’ll examine jQuery  later), the code might look something like:

var x=0;
for(x = 1; x<4; x++){
    document.getElementById("text"+x).onclick = function(){
        alert("test");
    };
}

Herein lies the complaint of JSLint: “Don’t make functions within a loop.” In the above code, on every iteration of the loop we will evaluate the function. This is wasteful and unnecessary. It’s much better simply to store the function in a variable:

var x=0;
var f = function(){
    alert("test");
};

for(x = 1; x<4; x++){
    document.getElementById("but"+x).onclick = f;
}

For many cases this will be sufficient,  but the above ignores the frequent requirement to pass values to functions. So how can we do this?

Well, in the above example a parameter will be passed to the function automatically. This parameter will be the event object that represents the source event. From this object we can infer the event source (e.g. an HTML button), and from the event source, we can infer object data.

Consider the following code (See it work at this JSFiddle):

var x=0;
var f = function(evt){
    evt.target = evt.target ? evt.target : evt.srcElement;  //cross-browser event target retrieval
    alert(evt.target.getAttribute("data-info"));
};

for(x = 1; x<=3; x++){
    var objButton = document.getElementById("but"+x);
    objButton.setAttribute("data-info", x);  //set a 'data-'attribute
    objButton.onclick = f;
}

Here we bind the data (x) to the control using the setAttribute() function on the object. We can retrieve this by calling getAttribute on the event target when the event fires. Refer to the JavaScript kit event object for more information on JavaScript events.

Or, of course, we can disregard the event obejct altogther, and instead use the JavaScript this object (available at this slightly updated fiddle)

var x=0;
var f = function(evt){
    alert(this.getAttribute("data-info"));
};

for(x = 1; x<=3; x++){
    var objButton = document.getElementById("but"+x);
    objButton.setAttribute("data-info", x);
    objButton.onclick = f;
}

The JavaScript this object is discussed in more depth over at QuirksMode.org.

And what about jQuery? Well, this can actually hide this sort of problem from JSLint. Consider the following:

$("input:button").each(function () {
    $(this).click(function () {});
});

This slightly contrived example (contrived because we don’t need to call the .each() to bind for all elements in the collection) will pass a JSLint scan, and yet, still break the rule that it was trying to preserve. We are still evaluating a function for every call of .each(), but JSLint doesn’t (and can’t) know this .each() functions as a loop.

But, adopting the pattern above in the same manner will solve this problem.

A Guide To JSLint Messages

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

, , ,

A programming convention that is frequently carried into JavaScript from other languages (often by C++ and C developers)  is the scoping of functionality within isolated blocks of code (i.e. between parentheses).

Take the following:

int y = 2;
{
    int x = 3+y;
    DoSomethingWith(x);
}

But JavaScript is less fussy about scoping, so the following will execute probably execute without complaint:

var y = 2;
{
   var x = 3;
}
alert(x+y); //alerts '5'

The use of the block here, therefore, is just extra noise. Its more characters to be written, read and transmitted. In addition to this, in some cases its contrary to the language specification. Consider the use of the ‘case’ statement:

var x = 0;
switch(x){
    case 0:{
            var y = 1;
            alert(y);
        }
}

Here we have added some parentheses to the ‘case’ block of code. In C, C++, this sort of convention is necessary. In JavaScript, it is not, so the following will work happily:

var x = 0;
switch(x){
    case 0:
        var y = 1;
        alert(y);
}

The first statement is contrary to the language specification. (Refer to the official EC5 Specification and the Mozilla JavaScript reference for more information). This reason alone is justification enough for JSLint to throw the error ‘Expected to see a statement and instead saw a block’, even before considering the extra noise the blocks create.

There is another potential argument against the use of (bogus) scoping blocks in this way. JavaScript also uses parentheses for objects and object literal declarations:

var y = {
    x:3,
    f:2
};

So, avoiding the specification of bogus scoped blocks will also make our code easier to read and subject to less confusion.

A Guide To JSLint Messages

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

, , , ,

With this message, JSLint is warning you of a potentially hazardous use of the decimal point. The following code will yield this error:

alert(.2);

Here. JSLint is picking out conventions that may be indicitive of some other problem in your code. It is also not making the assumption that every single JavaScript interpreter will handle this code correctly.

This is closely related to the message A trailing decimal point can be confused with a dot ‘{a}’

A Guide To JSLint Messages

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

, , ,

I kept stumbling across this one when investigating the message A dot following a number can be confused with a decimal point. This particular message proved easier to produce than the aforementioned one.

With this message, JSLint is warning you of a potentially hazardous use of the decimal point. The following code will yield this error:

alert(2.);

Here. JSLint is picking out conventions that may be indicitive of some other problem in your code. It is also not making the assumption that every single JavaScript interpreter will handle this code correctly.

This is closely related to the message A leading decimal point can be confused with a dot ‘.{a}’

A Guide To JSLint Messages

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

, , ,

This is a strange one, and took  some tracking down. Most attempts to bring about this message merely yielded another similar message: A trailing decimal point can be confused with a dot ‘{a}’.

Eventually I stumbled across it. So, what do you expect the following to yield?  (Readers should note that the space between the ’2′  and the ‘.x’ is intentional):

alert(2 .x);

Well, the answer is ‘undefined’.

Eh?

Things only appear to get stranger. Try this:

alert(2 .valueOf());

The alert here pops up with ’2′. Okay, so clearly it’s another way of writing the following…

alert(2.valueOf());

Right? Wrong! This merely yields a syntax error.

What’s going on here is best explained over at Stackoverflow: What’s going on with this rather peculiar JavaScript syntax?

A floating-point numeric constant must not have embedded spaces. Thus, ’2 .x’ is an expression calling for the constant ’2′ to be promoted to a Number object, and then the property called ‘x’ is examined. There isn’t one, of course, so the value is ’undefined’.

I can see why JSLint complains about it. The convention is so arcane that it’s probably not what the developer intended, and if they did then they really ought to have known better!

A Guide To JSLint Messages

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

, , ,

It could be argued that this is one of the family of messages under Expected ‘{a}’ and instead saw ‘{b}’. One of my university professor referred to as ‘error 1′, because it was the single most common and hard-to-spot syntax issue he encountered. Although he was a C programmer by trade, the syntactic similarities between C and JavaScript have allowed the issue to exist in both languages.

Here is some problem code:

if (x=0){
    //do stuff
}

What it is, of course, missing is a comparison operator. We have, instead, the assignment operator ‘=’ where would really be expecting an equality operator ‘==’, or, even better an identity operator ‘===’. We can see it in action in this JSFiddle.

The above code will return ’0′ which resolves to ‘false’, and therefore the block of code is not executed. Where it is non-zero it is assumed to be true, and the code is executed. Regardless, the statement is broken, or indicative of some very poor code.

Refer to this article on JavaScript operators for more information on:

  • arithmetic operators,
  • relational operators,
  • string operators,
  • logical operators,
  • bitwise operators, and
  • a few others that don’t really fit into any category.

A Guide To JSLint Messages

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

, , ,

JavaScript offers us a suite of functions for assisting the conversion from strings to numbers. While often done implicitly, it is good practice to perform the casts explicitly.

parseInt() is just such a function. It will convert a given value into a base-ten integer.

parseInt("40") //gives us 40.

As in the above example, the second optional ‘radix‘ parameter is often missed when calling the parseInt function. The need for this parameter becomes apparent when you consider numeric constants are interpreted as octal if they are preceded by a zero, and hexadecimal if they are preceded by a zero and x (0x).

The latter case does not often present us with a problem, however consider some of the following kinds of numbers that you may use in the course of your day:

  • Bank Account
  • Sort Code
  • Insurance Policy Reference
  • Dates/Times
  • Reference Number

It is fairly commonplace for these numbers to be zero-padded. Your bank account number might be 123456, but whenever you quote it, you will use the leading zero you were provided when you established the account. So when we pass this to the function it assumes it is an octal number.

alert(parseInt("0123456")); //alerts 42798

But not always! If the bank account had any 8s or 9s in it then the above would have worked. This would have been an intermittent bug to hinder your fault investigation yet further!

So, to alleviate any issues we add a second radix parameter, which tells the compiler the base of the number being passed. In every real-world use I have required of parseInt this number has been 10;

alert(parseInt("0123456",10)); //alerts 123456

Hexadecimal numbers utilise the six alpha characters A-F, so 16 as a radix parameter will suffice for hexadecimal parameters.However, there are 26 letters in the English alphabet, aren’t there. So, care to take a stab at when the following will give?

alert(parseInt("Z",36));

For the lazy but curious among you, the answer is 35.

So, there we have it. Every reason to include the radix parameter on your parseInt, and every justification for JSLint to flag it!

For more on numbers in JavaScript, refer to The Complete JavaScript Number Reference.

A Guide To JSLint Messages

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

, , , , ,