Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSLint Braces around If-Block

In Javascript, if an if expression does not have a curly bracket after it, the following statement is put inside the if block. That is,

if(foo)
bar();
baz();

is equivalent to

if(foo) {
  bar();
}
baz();

Douglas Crockford recommends not using the first because it is confusing and can cause hard-to-trace bugs if a programmer tries to add a statement to an if block without braces. For this reason, JsLint complains if you use the first form.

I use this all the time, and I feel like it's a non-issue provided that you put the statement on the same line as the if statement, like this:

if(foo) bar();
baz();

This is more concise visually than the full bracket form, and I've never had confusion with it. Just so I could pass JsLint and not have so much visual noise I have sometimes resorted to using a less idiomatic form that relies on operator short-circuiting, like this:

foo && bar();
baz();

You're probably all waiting for me to hurry up and ask a question, so here it goes: Is it generally considered bad practice to not use braces on one-line conditional statements if you format it correctly? Why? Is there a legitimate reason for JsLint to complain about it?

like image 792
Peter Olson Avatar asked Aug 07 '11 05:08

Peter Olson


2 Answers

JSLint checks if your code is Crockford-styled. There is a fork of it called JSHint that is customisable and much less annoying to work with.

Here is a code that validates well (apart from a tiny bug that will probably be fixed soon :)

/*jshint curly: false */

var a = true;
function work() {
    console.log('work');
}

if (a) work();
like image 101
Emil Ivanov Avatar answered Nov 05 '22 08:11

Emil Ivanov


In reading:

  • You might not be used to that coding style, and might think that this executes the two functions:

    if(foo) bar();
            baz();
    
  • Since JS has automatic semicolon insertion, there are even murkier circumstances. I, for instance, am not comfortable with what ASI would do to this code, even if I can reason it out:

    if(foo) bar()
            baz()
    

    It is not impossible to figure out or even hard if you know what ASI does, but ASI is a nontrivial algorithm. Having to run it in your head is expensive in terms of time, so it's better if you simply avoid ambiguous (in this sense, not ambiguous as per the ECMA-262 spec) situations.

  • It makes your lines longer than they need to be. This may be considered a non-issue depending on your coding conventions, if your condition is long, and your statement is as well, the resulting single-line statement will be more taxing on the eyes to read (it is well known that your eyes have difficulty reading very lone lines, hence paragraphing).

    You can, if you for some reason despite braces, still use something of the form:

    if(foo)
        bar();
    

    And that is virtually identical to the code you had, but I see no reason, at that point, not to just put the braces there.

In writing:

  • When you need to add another statement, it is not the case that you'll simply write it. You will have to refactor the surrounding area in order to do this. Again, this is not hard at all, but it is something extra to think about, which is not related to neither your problem nor your solution of the problem, it is merely a syntactical quirk.

    I think you already get the point, but it would be this scenario.

    Initial code:

    if(foo) bar();
    

    Changed code:

    if(foo) bar(); baz();
    

    You can see the problem clearly, but it might not necessarily pop up in a routine code review. If your testcases don't cover this specific codepath, this might get pushed to production because of repeated coder oversights, which are made easier by not requiring blocks be delimited explicitly. The solution you'd could adopt, as you have, is to say something like if(foo) bar() && baz(), but that would fail if bar() is falsy, so you end up with ugly stuff like if(foo) (bar(), baz()); which works, but is decidedly very ugly.


Personally, I use single-line if statements solely when the line is very short, and the algorithm itself is short as well. Something like if(extra_loop) --i; or if(!valid) break; When you start adding elses to these single-line ifs, the structure becomes more and more dangerous to manipulate.

In short, you can use it, but use it knowing the pros and cons, just like any other tool.

like image 39
Federico Lebrón Avatar answered Nov 05 '22 07:11

Federico Lebrón