Scott Logic Ltd

JSLint vs JSHint

Luke Page, March 28th, 2011

In January of this year Douglas Crockford decided that some of the options in JSLint were generally accepted and should always be on. One of those options was eqeqeq, the option to show an error if just two equals was used. For some time JSLint has complained about double equal comparisons against null, 0, undefined and empty string, but this change meant that two variables had to be compared without type coercion.

His point of view is that having a global style enforced through JSLint is a good thing and that the best way to do this would be to force anyone wanting to use JSLint to conform strictly to rules of his own devising. In his own words, here is a quote from the readme.

The place to express yourself in programming is in the quality of your ideas,
and the efficiency of execution. The role of style is the same as in
literature. A great writer doesn’t express himself by putting the spaces
before his commas instead of after, or by putting extra spaces inside his
parentheses. A great writer will slavishly conform to some rules of style,
and that in no way constrains his power to express himself creatively.
See for example William Strunk’s The Elements of Style
[http://www.crockford.com/wrrrld/style.html].

This applies to programming as well. Conforming to a consistent style
improves readability, and frees you to express yourself in ways that matter.
JSLint here plays the part of a stern but benevolent editor, helping you to
get the style right so that you can focus your creative energy where it is
most needed.

In the most part, I agree and perhaps the removal of the eqeqeq option isn’t the best example of things in JSLint I disagree with (see this article on coercion), but once a single author (even one as renowned as Douglas Crockford) starts enforcing specific style rules without any option to disable them, the tool becomes less useful and the audience becomes fragmented. It is a fine line between promoting consistency and being usable.

Because of these changes a couple of developers set up a competing linter, based on JSLint, called JSHint. In my opinion this project has gone too much the other way, allowing people to create an option to turn off any part of the validator that they can reasonably justify not wanting. For instance it supports not warning about automatic semi-colon insertion – an option I could never imagine wanting to turn on.

As the co-author of a JSLint plugin, I’ve had to consider whether to support JSHint and have decided to add support (it is a work in progress). The justification for supporting it are the following arguments which have been discussed on the JSLint mailing list over the last couple of months.

Linting Legacy Code

Taking over a project from developers who didn’t understand JavaScript and never applied a linter to it has meant that previous to December, there were a lot of errors raised per file. Not only are the errors now heavily multiplied, but JSLint also stops processing on several error messages. This means that the task to lint a file involves fixing one or two issues, linting, fixing one or more two issues etc.

It is no longer possible to lint a file to gradual levels of code quality. eqeqeq is perhaps the worst culprit here, because of the errors it is easy to introduce into code in the processing of linting – it is sometimes not possible to go through every possible place a field is modified or touched to make sure it stays a consistent type. Alternatively using casting to convert it to a type can clutter the code if you have to do it each time you do an equality comparison.

Even in the past, when converting from == null you had to remember that counter intuitively the ! is reversed…

if (a == null) {
}
if  (!a) {
}
 
if  (b!=null) {
}
if (b) {
}

So when running against legacy code, I would like to start with the big problems – syntactically incorrect code, missing semi-colons, unsafe line breaks and undefined variables and only fully lint a file with all the good parts when I understand the code and I know it will be thoroughly tested.

Loop Functions

the following piece of code now generates a breaking error that stops linting continuing.

var func = function (a, b) {
	for (var i = 0; i < a.length; i++) {
		if  (a[i] === b) {
			return i;
		}
	}
	return -1;
};
Error:
Problem at line 2 character 10: Move ‘var’ declarations to the top of the function.

for (var i = 0; i < a.length; i++) {

Problem at line 2 character 10: Stopping. (25% scanned).

The “onevar” option is off. This means that the code has to be re-written as.

var func = function (a, b) {
	var i;
	for (i = 0; i < a.length; i++) {
		if  (a[i] === b) {
			return i;
		}
	}
	return -1;
};

Now, I understand JavaScript variable scoping is not at the block level but at the function level, but a) what language allows defining in the for and then scoping it just for the contents of the for and b) why am I restricted from this, but allowed the following…

var func = function (a, b) {
	var i;
	for (i = 0; i < a.length; i++) {
		var v = a[i];
		if  (v === b) {
			return i;
		}
	}
	return -1;
};

Switch Indentation

I like JSLint to check my indentation but I disagree that the labels in switch statements should be at the same level as the switch.

var func = function (a, b) {
	switch(a) {
	case 1:
		return false;
	case 2:
		return true;
	default:
		return b;
	}
};

I see the argument that the code is indented by one level for each block, but I don't think this is enough of an argument to be inconsistent with the typical styling of other languages. This is perhaps my weakest argument and certainly one I would be welcome to accept defeat on if the other issues weren't so severe.

My Visual Studio 2010 plugin will support JSHint in the next couple of weeks.


This entry was posted on Monday, March 28th, 2011 and is filed under Blog.

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site .


14 Responses to “JSLint vs JSHint”

  1. Josh Salwen says:

    Do you have an ETA as to when you will update the Visual Studio 2010 plugin with JSHint support?

    Thanks in advance for doing this.

  2. Glad to hear about the update. This will make our developer very happy!

  3. Tim says:

    I have yet to find a valid reason to not use JSLint. The reasons you have given are not swaying my opinion at all. There is nothing wrong with enforcing style rules, this improves the consistency of code and is not difficult to do (in many if not most cases automatic). Every objection I have ever read about JSLint boils down to “old habits die hard” one way or the other.

    • Luke Page says:

      I wanted to provide a balanced article between a lot of the issues people have with jslint and why jshint was created. I continue to use jslint (not hint) for my code.

      I would be glad that any company is begining to use standards to regulate the code quality they use, whether they use jslint or a more relaxed approach with jshint. Often you have to persuade non technical business staff to pay for increasing the code quality, so I think it is only right to justify on a bugs caused vs cost to change existing code metric (which is what most of these complaints are aimed at – large chunks of existing code).

    • Tom Friend says:

      Tim,

      I’m happy for you and for Douglas Crockford. It’s good to have strong opinions. But it’s much better when a nice new tool comes along that doesn’t force YOUR opinions down MY throat, however you care to justify it. Judging from the wide and growing support for JSHint, I’m not the only one who feels this way.

      Luke, thanks for the plugin. It’s greatly appreciated.

  4. weaselspleen says:

    Requiring EXACTLY one space between ) and { isn’t style, it’s religion.

  5. spineless says:

    “Requiring EXACTLY one space between ) and { isn’t style, it’s religion.”

    Requiring EXACTLY one space between words isn’t style, it’s religion.

    ;-)

    • rubber knees says:

      >> “Requiring EXACTLY one space between words isn’t style, it’s religion.”

      I think a better analogy is “requiring two spaces after a period”

      What if the MS Word spell checker only worked if you accepted all of it’s grammar suggestions too?

  6. LoneCoder says:

    The idea that writing a book and writing code are the same is a silly starting point and honestly invalidates any arguments based upon it.

    They simply are not the same. Spaces between words has zero to do with how you space between ( or { or [. For example, meet me at and Meet meat have two differnent meanings. ( a + b ) and (a+b) mean the same thing and it’s pretty clear.

Leave a Reply

© 2013 Scott Logic Ltd. All Rights Reserved.