My JavaScript book is out!
Don't miss the opportunity to upgrade your beginner or average dev skills.

Saturday, May 28, 2011

My Last Comments On JSLint

Preface

I have been working with many teams and I have used JSLint on daily basis. This post is not about the tool itself, neither against Douglas work, this post is about developers often too religious about this tool.Finally, if you follow this blog you have already read tons of other reasons to think rather than "suffer silently this tool".It's my last post about it and I hope "it will not hurt your feelings".

Seriously guys, it's not that I think JSLint is all bad, but I cannot stop thinking it's simply an effect.The more I hear or read about developers being so religious about this tool, the more I feel to blame it.I am pretty sure Douglas will hate me for this post but I really hope he will read it 'till the end.

Douglas Talk At Falsy Values

Both me and big Doug were there, me for a workshop and Mr D. for his speech."Surprisingly" Mr Crockford talked about JSLint (again?!) and why it's so good.While many hints for newcomers are absolutely a must know, many others are absolutely inconsistent for senior JavaScript developers.There is a particular slide and a particular sentence Douglas said there:

... write code the way it's meant for the language ...

Above sentence was related to variables declaration, showing behind something similar to this classic example:

As all of us know, and if not we should, the reason JSLint would like to have all variables defined on top of the function is that no matter which condition, for or while loop, we have at some point, the parser will pre-consider all var in the same scope as local scope variables available since the very beginning.

(function () { // there is no "var" in this scope alert(something); // throws "Can't find variable: something" if (false) { // eventually global in ES3 and ES5 with no strict something = 123; }}());

The moment we define a variable local, even if we never reach that line, that variable is available for the whole scope, got it?

I can bet the amount of bullshit I can read in latter result is a shame for Douglas Crockford in first person, isn't it?

Not Only Inconsistencies

Another part covered by Doug speech was the withstatement ... here summarize:

... somebody (n.d. I guess me) may argue that the with statement may be useful in certain situations, but since it is always ambiguous and there is nothing that could not be done without it, the with statement should disappear from JavaScript ....

... and this is what happened.If we try "use strict"; activation in most recent browsers we can spot that the with statement is not allowed anymore, "thanks"!

A Tool To Rule Them All

It was actually a colleague of mine asking Douglas this question (or what I got about it) :

... so, you are saying that JS developers have no discipline, but don't you think that "dictating discipline" is not such easy task as well? ...

I honestly do not remember the answer but I am sure Douglas provided a proper one ... anyway ... what I do believe is that every developer has is own style, as long as syntax and readability are not too much compromised.If we use this tool thinking our code will improve any how we are first of all acting like machines plus we are not considering a "little detail" ...

Your Team Does Not Know JavaScript

Precisely! I know this is hard to face, but in 11 years of JavaScript programming I have never found a reason to have such tool that changes allowed programming language syntax defined by specifications ... fucking read them and stop winging! (and pardon my french)In few words, I have never had a single problem to understand any other piece of JavaScript code written by any possible developer out there but when I had a problem, and at the beginning of whatever programming language we all have, I have investigated, studied, and finally understood, what was going on in that piece of code and what was missing from my JS knowledge about it.Surely I did not blame the other developer, since if we would like to be monkeys on daily basis, of course we should use as many tools as possible that throw warnings even if the piece of code we wrote is absolutely correct, and we still have my precedent example few paragraph before as proof ...On the other hand, if we would like to master our JavaScript knowledge there is no way a piece of code that perfectly works could be screwed up because of JSLint.

Early JavaScript Days

When Douglas Crockford was still promoting JavaScript all over the world, nobody had any idea what he was talking about ... well, now we all have.This bloody language is absolutely everywhere and those "feeling cool" Java developers that still think JS is a toy are regretting 50% of their studies because they just don't get it ... that's why projects like GWT exists: developers that think JavaScript is a toy, write Java that is gonna be translated into Javascript ... and this is how powerful and flexible JavaScript is.In these days, and surely before, we truly need discipline and a lot of hints since as lazy developers we could not spend half a day reading ECMAScript 3rd Edition specs ... isn't it?In these days, and for these developers, of course JSLint has to be there, they don't know what they are doing but hey, at least they are willing to learn something more from this tool (and most likely behind a syntax translator such GWT is, created to do not throw JSLint warnings ...) .As demonstrated before, this is not enough.Java skills into JavaScript language are similar to me pretendng to have Alex Martelli knowledge using Visual Basic 6 on daily basis ... I hope you know what I mean ...As summary, if you think you can move knowledge from another programming language without deeply understanding the new one pretending you come from "something better" you are half way trough your own failure.At the end of the day it may not matters, as long as the next point is clear for everybody.

TDD And Unit Tests Are The Only "Safer Way"

Yeah you read it right ... there is no way our JavaScript code is gonna be any safer because of JSLint or whatever JS validation tool: no fucking way!If we think that === rather than == is all we need to be safe, without understanding why we may be safer or why we may do something simply redundant without considering cases where we want to ==, we have never been so wrong.Unit Tests, and more Unit Tests on top of Unit Tests are the only answer to our code quality!It does not matter how we write routines as long as real Senior Developers can understand it, simply asking more if they really don't, and as long as all our possible implementation cases have been considered.If we are those kind of "my code pass JSLint, my code is better and safer and cleaner" develoeprs, we are simply demonstrating how much we still have to learn about programming.I don't know any other language that religious or with need of these kind of "natural programming code evaluation tools" and we all know JavaSscript is not the first programming language ever, neither the last one.If it's about some common code convention we don't need JSLint, we simply need a bloody wiki/web/infrastructure page able to explain it so that somebody else could eventually blame it the moment he's flexible enough to understand meant edge cases.This is what I have answered as well during my workshop when somebody asked me what I think about JSLint, while the whole post is the reason I did not even start arguments or questions after Douglas speech, and the reason I will never do it.We all have our style, Douglas has his own one, and I am happy for him he is that consistent.Should I be a Douglas Crockford clone on daily basis? Hell no, since as I have said: I know WTF I am writing and why

There was kind of a similar discussion about HTML validation/validators last year (see http://www.nczonline.net/blog/2010/08/17/the-value-of-html-validation/ and http://www.highresolution.info/weblog/entry/alles_valide_oder_was/). Quite a few people seem to be super serious about having valid HTML, but still produce unnecessarily blown-up markup for example (which can be perfectly valid regarding the syntax, tag nesting etc.). So I definitely get your point, Andrea, though I don't really understand the anger I sense in your post. But that might just be another matter of style :)

My main problem with JSLint also is that I can't really customize it. But as Paul mentioned, there is JSHint for example.

@Sergio: at Falsy Values Douglas explicity mentioned that he didn't say there are no use cases for "with" (so he's probably far from "hating" it). He just thinks there are alternative ways to get the same results without the ambiguity which ->might<- come into play.

Oliver, the anger comes after a depressing week and me tired, at the end of the same, to hear developers saying stuff like: "JSLint may avoid some code review" or "with JSLint my code is safer" or "we collect a list of warnings and we blame developers on top"

There are many cases where lint is good but unfortunately people spread around that JSLint is a must have and if JSLint is bad, it must be ... I am kinda against developers that follow in a passive way suggestions, specially those coming from an automatic parser which cannot possibly understand edge cases.

Last, but not least, I have asked years ago the possibility to avoid warnings via /*@ignore:true*/... code .../*@ignore:false*/ and nothing happen: I am still a noob for this validation tool ...

I had a tech talk at a ...khm... well-known company about jslint. Eventually, it came about to the point of list your vars in a single line (which is a switch in jslint).

It turned out, while they were pro of listing all vars on the top, but they wanted to do it with multiple var statements instead. They had such compilers I guess which would get rid of this redundancy in minified code anyway.

I said "fine, if that's your desired coding convention as a team, just patch JSLint, or choose another syntax checker".

They looked at me like I was mad...

Linting tools are tools. I believe TDD/jsunit is a tool too. Sometimes it has considerable benefits to use them, sometimes you have to cut them to your own needs.

To start with (why is the comment box so tiny?), I'm not pro-JSLint. Actually, I came to your blog after searching for some good commentary that would help me decide whether or not to use it as quality testing tool in a project I've started. I'm not a javascript guru by any means, but I noticed that no one had anything to say about your examples:

something(); // second references available in this scope // local scope variable var oneTwoThree = 123;

// return the local function call return something();

}());

If you happen to call something() after you've declared it, but before you've declared the local var oneTwoThree, you've got a problem: oneTwoThree is assumed to be a global var because the local one doesn't exist yet. Therefore, in this particular case, it's a probably a good idea to stick the var declaration at the top of your anonymous function declaration.

That first call to func() does not return "undefined". It returns "123" when you run it in a browser console (but your last statement, the function declaration, returns "undefined" so you'll actually have to examine checkWhatever). I do see your point, however I would like to rephrase the above example in terms of the previously discussed example:

Though the first case may not be an error to the js interpreter, it would be contributing to a broken app and it may even be difficult to track down why the app was broken, because there's no "error" reported. Yet, moving the var declaration/initialization to the top of the anonymous function fixes the "not-an-error" error. Notice that I didn't move the declaration for func(){} any where. I don't know the deep-tissue, technically specific reason why this "works" (var whatever is properly defined during the invocation of func), but it's just one example of why declaring vars at the top of a function makes sense. On the other hand, here's something about JSLint that is really bothering me:function doSomethingWithNodes(nodes){ this.doSomething();

WTF?!! JSLint just won't move forward unless I take the "var" out of the for-loop, even when it is previously declared at the top of the function. According to the "JavaScript Pocket Reference" (David Flanagan, 2012):

"It is legal and harmless to declare a variable more than once with the var statement. If the repeated declaration has an initializer, it acts as if it were simply an assignment statement."

So in the latter case, the var in the for-loop is NOT a variable declaration, but simply an assignment statement, because the variable was declared at the top of the function. That does it, I'm tossing JSLint out the window...

this is a very old post and I already use JSHint and discussed JSLint problems all over this blog. Feel free to use it if you think is the right tool for you .. it won't be the right tool as soon as you move into ES5 world where you can control enumerability, as example, and you have new kind of objects that JSLint won't let you ignore. Moreover, problems with == null etc ... but trust me, no need to explain me anything since it's explained already here and in many other places. JSLint is not what I'd suggest to anyone out there. You do what's best for you, of course.