Out of Hanwell

June 5, 2006

JSLint considered harmful?

Filed under: Uncategorized — Matthias Miller @ 8:54 am

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 lints–JavaScript Lint or JSLint–are helpful or harmful.

  • Is eval evil? There’s one situation that JSLint correctly warns against. Sometimes I see code like this to retrieve property values: eval("myobj." + prop), when instead it could simply be myobj[prop]. The problem, of course, is that I use JSON in my code, and I need to use eval.

    JavaScript Lint does not warn against the use of eval.

  • ==/!= vs. ===/!==

    JSLint also prohibits “== null” and “!= null”, but there is a perfectly good use of these notations – the common case where you really don’t care to distinguish between null and undefined, but do wish to distinguish those from other “false” values.

    To be honest, I implemented this warning in JavaScript Lint because JSLint had it. I tend to use strict warnings whenever possible, so I’ll either use if (x === 0) or if (!x), but rarely if (x != null). The argument against the warning is very a good one.

    This warning can be disabled in JavaScript Lint.

  • Required curly braces on all block statements. When I e-mailed Douglas Crockford, proposing a patch that would make this optional, he responded that this is a very common error. For example:

    if (c)

    I disagree. I work on a 7000-line JavaScript codebase (still growing), and I’ve never encountered that problem. I’ve also worked with a developer who had no prior experience in the Java/C/C++ language family, and I recall no incident of this bug in that developer’s code.

    This is one of few warnings that are disabled by default in JavaScript Lint.

  • Repeated “var” declarations.

    JSLint’s prohibition against repeated “var” declarations can lead to fragile code:

    function foo() {
    for( var i = 0; i < a.length; i++ ) {
    // and later in the function:
    for( i = 0; i < b.length; i++ ) {

    If you later refactor that code, it would be easy to forget to put the “var” back in.

    This warning can be disabled in JavaScript Lint.

    Both lints, if they are enabled to detect undeclared variables, should warn you if you refactor code and forget to put it back in. The “declaration warning” could reasonably be suppressed if you immediately assign a value at the second declaration. The concern, I think, is that you forget that this variable may have been previously assigned.

  • JSLint disallows i++ and i– for no good reason. Rather than warning against all uses of the ++/–, JavaScript Lint only warns when it’s used as part of another statement, such as x = --i or if (i--). It’s not that prefix/postfix increments/decrements are inherently wrong. It’s just that they’re hard to get right when they’re used within an expression.

    This warning can be disabled in JavaScript Lint.

Are lints useful or harmful?

To be useful, the lint must adapt to your code, rather than your code adapting to the lint. I believe that’s the most significant difference between JavaScript Lint and JSLint. Speaking of the curly-brace-blocks setting, Douglas Crockford told me, “Laxity defeats the whole point of a lint program.” To some degree, he’s right. But lint programs must also be very pragmatic.

JavaScript Lint is loaded with configuration options. In fact, every warning mentioned here (besides the eval warning, which JavaScript Lint doesn’t have) can be disabled in JavaScript Lint. Yes, this makes JavaScript Lint more difficult to configure, but these settings are also what allow JavaScript Lint to be run on large codebases.

I don’t use JavaScript Lint as the final sign-off for correct code. I simply use it to find the most common typos, syntax errors, and dumb goofs before I test my page in the browser. I validate my code in three ways:

  • JavaScript Lint, for initial checking. (I also run JSLint during a nightly build process, but I prefer JavaScript Lint when I’m coding because it’s so much faster.)
  • Unit tests, for core reuseable components.
  • Manual tests for integration testing, cross-browser quirks, and such.

Lints can be very useful if they’re used right. But if they’re not, Michael Geary is quite right in calling them harmful.



RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Blog at WordPress.com.

%d bloggers like this: