JSLint Considered Harmful

Did JSLint actually reveal *any* hidden bugs, or did it just complain about
perfectly legitimate coding practices such as eval? Douglas Crockford is
obviously a JavaScript expert, but some of his ideas on coding style are
strange and counterproductive.

Comments (21)

Just to clarify (and avoid making enemies!), I’m a huge fan of Douglas Crockford and his work. When I said “JSLint considered harmful” I was referring specifically to the snafus with jQuery and the stylistic nitpicks. JSLint looks a valuable tool: Now that I know about it, I’m going to start using it myself. I’ve had bugs in my own code that JSLint would have found. I’ll just know to take its warnings with a grain of salt.

On JSLint.com, Doug solicits feedback about the program and asks specifically if it is too strict about any of its warnings. What would be perfect is the ability to turn off any of the warnings, as it allows now for a few of them.

As a quick and dirty fix for my own use, I’ll probably just grab a copy of the code and comment out the warnings I don’t want.

JSLint considered harmful
Dean Edwards pointed to a comment by Michael Geary regarding JSLint. Although I cannot speak on behalf of JSLint, I can speak on behalf of JavaScript Lint. I’d like to first respond to the specific situations, then to the larger question about whether…

I echo Michael Geary’s comment–after I responded to this post, I edited my response somewhat to clarify that the problem is not really with JSLint. Douglas Crockford’s thinking was really the catalyst behind much of what I think and do regarding JavaScript, despite our different ideas about coding practices. It’s all about the shoulders of giants, I guess.

For a lint tool to be really useful, it should be an automatic part of your testing procedure. If it always spits out a few meaningless errors then you’ll miss the important ones when they’re in the middle of them. You’ll soon get tired of interpreting the results. So I think a lint that cries wolf just isn’t very useful.

Another harmful post? Well in all due respect, it’s much more helpful than it (possibly) is harmful.

All in all, if you know what you’re doing, you know which errors to turn on and which ones to turn off. Use eval in the proper places, and take them out when you might have screwed up. This argument can go both ways. If you take it out but yet you’re polluting your code with unecessary eval’s then yea, it would be nice if a tool would catch those.

The eval function is the most misused feature of JavaScript. That misuse is compounded by a design error in JavaScript which gives the evaled text way too much authority. JSLint assumes that eval is being misused. There are a few cases (such as the parsing of JSON text) where use of eval is correct. Because of those cases, JSLint provides a switch to turn the eval check off. I am puzzled why you created a $.eval alias. I can’t make any sense of that. Perhaps JSLint should look for use of eval as a method, so that others can avoid the same mistake.

Many of JSLint’s tests came from observing the comp.lang.javascript news group. Frequently, people would post pleas for explanation for why their code didn’t work. I saw many instances of things where the programmer misunderstood JavaScript’s sense of falsiness, and compounded that with a misunderstanding of JavaScript type coersion under the == operator, resulting in a difficult to diagnose error. I designed JSLint so that such errors could be detected automatically. It comes at the cost of a consistent and rigorous coding style.

JSLint does not disallow — and ++. It does provide an optional check for post-increment and post-decrement because these have been implicated in many of the worst buffer-overrun security errors. I found that when I stopped using them, the quality of my own programs improved. You may have different quality goals, so you don’t have to activate that test.

If the source is as JSLint expects, it generates a function report. It lists for each function:

* The line number on which it starts.
* Its name. In the case of anonymous functions, JSLint will “guess” the name.
* The parameters (including arguments if used).
* The vars.
* The global vars. An unexpected item here can be an indication of an error.
* The labels.

You can include in your program a comment that lists the global functions and objects that your program depends on, but that are not defined in your program or script file. Including this information can improve the quality of the report that is generated.

An external declaration can look like this:

/*extern getElementByClass, breakCycles, JSONRequest */

A global declaration starts with /*extern. Notice that there is no space before the e.

Select the Assume a browser option to predefine standard global properties that are supplied by web browsers, such as window and document and alert.

@Juanito – I agree that eval is often misused. It is a powerful feature of the language however. Take a look at the source code of any of the major JavaScript libraries and you will find an eval somewhere. Are library authors doing something wrong? Of course not. Those calls are deep in the code and are accessed rarely but they are needed.

Ironically, I just today made some code work in your JS Packer only because JSLint (running through TextMate) found code that did not adhere to Packer’s requirements (of ending every line with a semi-colon).

Since the code I was trying to pack was from a large group project w/thousands of lines of JS, after looking to make sure FUNCTIONS ended with semicolons, I was all out of ideas until JSLint sniffed out the problem for me.

Who knew? Well, OK, *you* did, but I didn’t, and it saved me quite a bit of time!

Go JSLint!

Comment by: Mark Johnson

Posted: 2007/09/10 9:53 pm

Comment: #15

[…] Some argue that this does not really catch bugs and instead a comprehensive unit-test suite should be used. This might be a requirement for a platform level Javascript library code, but it is often an overkill for your little site with some flashy dialog windows. […]

I use JSLint first any time I have more than a few lines of code because it saves me time. Being told exact lines to fix things and my code running right immediately after that is so much nicer than tromping through trying to find what the browser is complaining about.