

A JavaScript Quality Guide - bevacqua
https://github.com/bevacqua/js/

======
kevincennis
If you're going to have your team agree on _any_ style rules at all, then
automated style checking is the only way to go.

Let the computer yell at people so you don't have to.

Nobody wants to be the pedantic jerk who has to leave comments on a PR about
whitespace or single vs double quotes.

When you use an automated style checker, you presumably catch those errors
_before_ a PR gets submitted and nobody ever has to be the bad guy/girl.

~~~
akbar501
> automated style checking is the only way to go

Absolutely. We've found automated style checking also improves quality and
efficiency. Even the "pedantic jerk" can miss small style issues that are
easily caught by tooling.

For anyone wondering what tools. The most common for JS are JSHint and JSCS.
Then use Grunt or Gulp combined with a watch to check a file each time a
change is saved. Lastly, use a precommit hook (or similar) to check again
before code is committed into the repo.

------
gorhill
I learned something: I didn't know that the difference between:

    
    
        function foo() {
        }
    

and

    
    
        var foo = function() {
        };
    

Was that with the first form foo() will always be declared and available for
use inside a scope, while the second form depends at which point it is
declared.

But I had read somewhere (can't remember where... jshint?) a long while ago
that using the latter form inside scopes was better, so I've adopted that.

I don't think I will go with the guide for this one, since not having the
function defined automatically is often useful, to avoid overhead of
instantiating the function for when it's not going to be used due to code
flow.

~~~
spmurrayzzz
This is referred to as "hoisting". As an aside, technically the latter's `var`
declaration also gets destructured and hoisted as such...

    
    
      var foo;
      ...
      foo = function() {
    
      }
    

Also another difference in the latter is that its an anonymous function, which
is commonly seen in assignment expressions — but you could also name it for
more informative logging.

    
    
      var foo = function realName(){};

~~~
pyre
Naming the anonymous functions, is actually suggested as good practice
somewhere in the Angular.js docs. I came across that a couple of weeks ago.

~~~
whiskypeters
Naming anonymous functions (and anonymous function expressions) provides
useful context while tracing error stacks

~~~
pyre
This was exactly the reason it was suggested in the Angular.js docs.

------
nailer
> Always put 'use strict'; at the top of your modules.

'use strict'; should be in the top of the scope you control. A global 'use
strict'; would place the global scope into strict mode, so all your imported
modules would be under strict mode too, and then third party code would break
and you don't know why. IIRC jshint will pick this up.

To be honest, the whole guide seems like a shorter, less comprehensive version
of the JS community's own Idiomatic JS
[https://github.com/rwaldron/idiomatic.js/](https://github.com/rwaldron/idiomatic.js/)

~~~
bevacqua
That's what that means. In CommonJS the top of the module is the topmost
scope, in systems like RequireJS its the first thing in your closures

------
couchand
I'm not convinced that this guide is very good. On many of the issues the
actual decision is punted in favor of "just make sure it's consistent". Well
obviously, that's why there's a guide. The purpose is to lay down the law so
everyone knows HOW to be consistent.

Moreover, a few of the suggestions introduce serious performance issues,
notably around iteration and the treatment of the `arguments` object. If you
haven't yet, please do check out Petka Antonov's Optimization Killers [0].

[0]:
[https://github.com/petkaantonov/bluebird/wiki/Optimization-k...](https://github.com/petkaantonov/bluebird/wiki/Optimization-
killers)

~~~
nailer
It really depends on whether performance is an issue, and the cost of the
optimisation.

A common example: lodash searches function toString() with regexps as an
optimisation technique, underscore doesn't. Both are correct, maintaining
lodash requires knowledge of how and why the hack works, but OTOH lodash is
faster. Maintaining underscore is cognitively simpler but the resulting code
is slower.

~~~
couchand
I'm all about making sure that code is optimized for humans first and
computers second.

Here is the specific remark I was referring to: _Or even better, just use
.forEach which doesn 't have the same caveats as declaring functions in for
loops._

Blindly applying forEach is simply not the right answer here.

~~~
nailer
I'd suggest the opposite: forEach() is smaller that iterating over indexes and
creates a scope by default which (although having overhead) will prevent a lot
of common last-case-wins scenarios that frequently trap both new and
experienced developers.

Should we use a .forEach() for a 1 million item array? No. Performance would
be a problem. For the typical use case of items like the demo [1, 2, 3]? Yes,
this would be be simpler.

------
weego
The best quality/style guide I've ever been given was: "our code will be read
many more times than it was written, don't do stupid shit". Having worked in
that team for a while I really can't see any use for this kind of granular
detail, other than if you goal really is over-zealous control.

------
acconrad
Not really sure we need another one of these: Idiomatic.JS[1] is far more
complete, and if you want an opinion, just seek the style of Google[2].

[1] =
[https://github.com/rwaldron/idiomatic.js/](https://github.com/rwaldron/idiomatic.js/)

[2] = [https://google-
styleguide.googlecode.com/svn/trunk/javascrip...](https://google-
styleguide.googlecode.com/svn/trunk/javascriptguide.xml)

------
chdir
> Keep regular expressions in variables, don't use them inline. This will
> vastly improve readability.

Although it might introduce inadvertent bugs. I prefer not to follow that
advice to avoid running into the 'lastIndex' problem described here [1]. There
are other ways to avoid it like not using the 'g' flag or resetting lastIndex.
However not storing regex in a variable is also useful to avoid that headache.
You might argue about performance but for a good majority of the cases, it
doesn't matter practically.

[1] [http://stackoverflow.com/questions/1520800/why-regexp-
with-g...](http://stackoverflow.com/questions/1520800/why-regexp-with-global-
flag-in-javascript-give-wrong-results)

[2] [http://stackoverflow.com/questions/13500519/difference-
betwe...](http://stackoverflow.com/questions/13500519/difference-between-
regexp-constructor-and-regex-literal-test-function)

------
frik

      Semicolons ;
    

It seems to be fashionable recently to omit semicolons from Javascript. For
example GitHub (internal) and zepto.js have jumped on the no-semicolon
bandwagon, requiring their omission in any code.

[http://programmers.stackexchange.com/questions/142086/why-
th...](http://programmers.stackexchange.com/questions/142086/why-the-recent-
shift-to-removing-omitting-semicolons-from-javascript)

OP's guide mentions "Avoid headaches, avoid ASI. Always add semicolons where
needed", that's a good advice IMHO.

Edit: I would add:
[http://programmers.stackexchange.com/a/142114](http://programmers.stackexchange.com/a/142114)

~~~
mnarayan01
> Always add semicolons where needed

Perhaps overly pedantic, but this seems a little...vague.

~~~
EvanYou
That's why I don't like guides that suggest people to mindlessly add
semicolons everywhere. If you don't really know how ASI works you are always
living in the fear of missing a semicolon somewhere. Actually learning how ASI
works liberates you from that fear and you can still opt to use or not use
semicolons.

~~~
mnarayan01
I think I'm actually in total disagreement with this. I think using semicolons
as statement terminators is quite easy and doesn't require any knowledge of
the ASI in terms of _adding_ semicolons. The one (potential) issue with not
being aware of the ASI when using semicolons as statement terminators is for
something like:

    
    
      return
        {
          a: 0
        };
    

since you can't disable ASI. Even in the above case, however, "standard" JS
style would prevent the issue.

~~~
EvanYou
Relying on "standard JS style" is as reliable as relying on ASI without
knowing how it works.

If what you are saying is with "standard JS style" you will never add a
newline after return, then I can also assume with "standard JS style" you will
not:

\- start a line with ++ or --

\- start a line with a regex literal

\- split a for statement into separate lines

So, the only issue you need to be aware of when writing semicolon-less
javascript is when you start a new line with ( or [. Easy enough to remember,
no?

I've personally been writing semicolon-less JS for almost two years now, and
this one simple rule has been more than enough.

------
EvanYou
Don't confuse quality with style. If you want provide a quality guide, include
only rules that actually improve the quality of the code, don't include style
preferences. Style is subjective by nature, but quality not so much. Some
rules being enforced in this guide are heavily opinionated and yet have no
direct correlation with code quality. What does the indentation being 2 spaces
or 4 spaces or tabs have to do with code quality? And a semicolon-less
codebase can be as clean, readable and performant as one with semicolons, your
arguments against ASI is simply FUD. As many have pointed out, for these
stylistic disagreements the only rule should be "just be consistent".

------
mattfenwick
I'm confused by what "Style checking" ([https://github.com/bevacqua/js/#style-
checking](https://github.com/bevacqua/js/#style-checking)) means.

Aren't many of the other suggestions precisely "style checking" concerns?
Semicolons, spacing, string quotes, conditional brackets, etc. ?

Not to say that there isn't a difference -- just that I don't see what it is.

~~~
bevacqua
Automated style checkers such as jscs

[1]: [https://www.npmjs.org/package/jscs](https://www.npmjs.org/package/jscs)

~~~
madeofpalk
what's the difference between a style checker like jscs and a linter like
jshint/jslint?

~~~
akbar501
They are similar and have some overlap. However, the overlap is not 100%, so
it's good practice to use both jshint and jscs together.

jshint is a static code analysis tool to identify and flag errors/potential
errors in JS code. jscs is purely a style checker.

------
jasonkostempski
I've been using JSLint with default options for years now. It's blissful not
having to think about this stuff anymore.

------
progx
Is this similar to
[https://github.com/airbnb/javascript](https://github.com/airbnb/javascript) ?

------
yoanizer
Don't sweat the small stuff.

Really how you place your {} will never make or break your project. Focus on
what really matters.

~~~
bevacqua
Glad you got that. Some people are adamant of letting go of their obnoxious
style checkers that do nothing but waste everyone's time

[https://github.com/bevacqua/js/issues/2](https://github.com/bevacqua/js/issues/2)

------
netcraft
Does this do something more than jshint?

~~~
aikah
there is no code it's just an markdown text file.

------
aikah

         var message = util.format('oh hai %s!', name);
    

I thought it was a javascript quality guide ? there is no util.format in ES5
spec.

~~~
iaskwhy
"Usually you'll be a happier JavaScript developer if you hack together a
parameter-replacing method like util.format in Node." \+ "You could implement
something similar using the piece of code below."

I don't think you can ask more than this, everything is clearly laid out...

------
okcoker
You lost me at 2 spaces

------
MrDosu
Stopped reading after 2 spaces. 4 spaces is the law!

~~~
Bahamut
I think you'll find that most frontend developers despise 4 spaces...at least
that I've come upon anyhow. I only ever met one developer that liked 4, and
that person is a tab guy to boot.

~~~
Raphmedia
I'm a front-end guy and I love my 4 spaces. Helps a lot with complicated HTML
to have the extra spaces to easily see what is what. It's also very useful in
SASS and Less, where you have nesting.

