addyosmani-com by hsits

VIEWS: 15 PAGES: 11

									                                                                                                                           Tweet   349




Today we're going to explore JavaScript style guides, specifically: their importance, style guides worth reviewing and tools that can assist in
automated code beautification or style enforcement.

What exactly is a style guide?
Before we begin, let us remind ourselves exactly what a code style guide is:

A style guide or style manual is a set of standards for the writing and design of code. The implementation of a style guide provides uniformity in
code style and formatting, often covering guidelines regarding indentation (tabs vs. spaces), variable and function naming conventions, where
best to apply whitespace and so on.

Why is consistent code style important?
They say that good code is it's own documentation. Whilst I don't completely agree with this (docs are important!), the fact is, the more
readable our source code is, the easier it is to maintain.

Following a consistent style guide both helps enforce this concept and improves the overall quality of the code we write. This facilitates other
developers stepping in to assist with maintenance more easily and can certainly save time in the long haul.

Readable source code is arguably easier for us to understand as well. It's easier to browse, locate and fix bugs in and more easy to optimize. It
can also give us a clearer picture of how the code fits into a larger body of work. This is not to say that poorly styled code is badly written code.
Indeed, I've seen several cases of code which were styled quite poorly, but were in fact, very efficiently written solutions on the whole.

Consistently styled code can:

   Reduce the lead time required to understand an implementation
   Make it easier to establish what code can be reused
   Clarify how updates to an implementation should be styled or structured (remember that consistent code, even when written by a team,
   should look like one person wrote it).

Are developers really using style guides in practice?
Advocating for the use of style guides is great, but it doesn't mean a great deal if only 1% of developers are seriously considering using them.
To get a better gauge on this, I did an informal survey on Twitter, asking developers whether they were using a style guide for the JavaScript
they were writing.



                                                                                                                         converted by Web2PDFConvert.com
I received a relatively good sampling responses, below of which are a few:

   Rodney: Pretty much the jQuery style guide – just without the insane amount of whitespace
   Sindre: Idiomatic.js of course, with single-quotes and tab indention
   D.Cherman: There's no precedent in my group, but I'm pushing towards following the guidelines in idiomatic.js
   Marek: I use Crockford's style all the time, unless I'm contributing to a project that doesn't
   Jack: I use my own JS style guide, which essentially is a mash up of all the popular ones out there, very similar to them too
   Matt: Yes (based on jQuery and Idiomatic) but so long as projects are consistent then I'm flexible
   Jamie: I'd use an existing one in a team I was joining, or propose we agree on a standard if 1 wasn't in place. Happy with any style at all,
   just as long as there is one – so it reads like one person wrote it all. Just my opinion.
   Arthifiji: At work we are planning to use coding and style guides from Google. We have found it to be very comprehensive

Recommended JavaScript Style Guides
For developers interested in improving the code style consistency of the JavaScript they write, I'm happy to recommend the following style
guides:

1. Idiomatic.js. This is not only highly recommended and very comprehensive, but is also the style guide we've adopted for several of the
   projects I'm involved in. It includes contributions by jQuery core contributor Rick Waldron, jsPerf contributor Mathias Bynens and many other
   experienced JS devs in the community. Not all developers agree 100% with the practices it advocates, but that's the great thing about a
   forkable style guide – it's easy to adapt to your own needs.
2. jQuery Core Style Guide. Perhaps the most popular style guide modern JS developers are aware of, it is used by the jQuery core team,
   jQuery UI, QUnit and many other projects. Rick Waldron once again had a hand in this as have Adam Sontag and John Resig, also of jQuery
   fame.
3. Google JavaScript Style Guide. Written by former Google JavaScript developers such as Robby Walker (Closure Linter), this contains several
   readability best practices that those from a particularly traditional software engineering background will appreciate. Further comments on it
   can be found here.
4. Dojo Style Guide Another very comprehensive alternative by the people that brought us the excellent dojo toolkit. Interestingly this guide is
   based on the structure of the Java programming conventions guide. If you like what you see, you might also appreciate dojo's inline
   documentation sguide, which remains my favorite style of inline commenting in JS.
5. Aloha Editor JavaScript Style Guide This guide comes from the authors of the relatively non-trivial contentEditable-based Aloha Editor. Whilst it
   recommends the jQuery style guide, it has some useful (minor) additions such as how they suggest styling AMD modules.
6. Crock's Code Conventions For JavaScript Another good guide, although perhaps not as detailed example-wise as others. I feel this has been
   superseded by Idiomatic.js, but if you strongly disagree with it or the jQuery core style guide, this is a much recommended fallback.
As two developers mentioned using the NPM style guide for their projects, I'll mention it in passing. Designed with reducing visual clutter in mind,
this minimalist guide does contain similar practices to those seen in other guides above but is probably what I would consider a 'light' set of
guidelines. The recommendations in 1-6 should definitely be considered more comprehensive.

Note: I've reviewed all of the above and discarded some other guides that were either entirely too brief/vague or (in my opinion) not that useful at all (e.g
the GitHub JavaScript style guide).

A Tutorial On Applying The Principles Of Idiomatic Code Style
Let's go through a brief tutorial. Here is a functional block of code that doesn't follow any particular guidelines on code style:

             view plain copy to clipboard print ?

       1.     function foo(bar,baz,fum){
       2.         var hello = "Hello";
       3.         var ret;
       4.         var num = 1;
       5.         for(var i = 0; i < bar.length; i++) {
       6.             var out = bar[i];
       7.             if (out === ""){
       8.                  ret = fum(out) + baz(out);
       9.             }
       10.        }
       11.        if (!(ret == undefined)) {
       12.            return ret;
       13.        } else{
       14.           return fum('g2g');
       15.        }
       16.    }


                                                                                                                                converted by Web2PDFConvert.com
There's technically nothing wrong with it that would prevent it from running, but it could certainly be improved.

In order to better appreciate the impact of a consistently readable code style, let's go through this sample line-by-line and compare how it would
look if we were to apply the Idiomatic.js style guide to it.

We will compare what the code looks like before and after it's been stylized and I've added notes in case it isn't clear on first glance.

1.Named function declarations

Before:

              view plain copy to clipboard print ?

         1.    function foo(bar,fum,baz){


After:

              view plain copy to clipboard print ?

         1.    function foo( bar, fum, baz ) {


What changed? We improved readability by:

   Forcing consistent spacing before each of the arguments
   Ensursing this accounts for a space after the function's opening bracket and before the closing bracket
   Adding a space between the closing bracket and the opening brace of the next block
2.Variable assignments

Before:

              view plain copy to clipboard print ?

         1.    var hello = "Hello";
         2.    var ret;
         3.    var num = 1;


And we also had inline variables in our for loop:

              view plain copy to clipboard print ?

         1.    for(var i = 0; i < bar.length; i++) {
         2.        var out = bar[i];


After:

              view plain copy to clipboard print ?

         1.    var ret,
         2.        out,
         3.        hello = "Hello",
         4.        num = 1,
         5.        i = 0,
         6.        l = bar.length;


What changed?

   We moved to using one 'var' per functional scope to promote readability. As the Idiomatic guide states, this allows our declaration list to be
   more free of clutter
   We moved the inline 'var' declaration for i from inside our loop to this same list. bar.length was cached in this same list under a variable l
   to avoid having to recalculate the length of bar each time.
   We moved the 'var' declaration for out to this list. This follows the idea of only declaring new var s once in our scope
3.Loops:

Before:

              view plain copy to clipboard print ?



                                                                                                                         converted by Web2PDFConvert.com
         1.    for(var i = 0; i < bar.length; i++) {


After:

              view plain copy to clipboard print ?

         1.    for ( ; i < l; i++ ) {
         2.        out = bar[i];


What changed?

   Consistent whitespace is now used throughout the loop definition
   Specifically this is done (i) after the for keyword and prior to the opening bracket, (ii) between each expression/statement within the loop
   and (iii) prior to our opening brace
   By setting our pointer i to 0 prior to the loop, we can avoid the need to define this inline.Instead a simple semi-colon can be used in it's
   place, which some developers argue reduces clutter. Note: Hoisting the counter declaration to the top of the function is only a stylistic choice
   here and can be avoided if you feel uncomfortable with it. I personally would usually keep it inline to avoid detracting meaning.
4.Conditional evaluation:

Before:

              view plain copy to clipboard print ?

         1.    if (out == ""){
         2.        ret = fum(out) + baz(out);
         3.    }


After:

              view plain copy to clipboard print ?

         1.    if ( !out ) {
         2.        ret = fum( out ) + baz( out );
         3.    }


What changed?

   Rather than evaluating out is empty, we can instead evaluate falsy-ness instead (i.e !out ). This both requires fewer keystrokes and is
   arguably more readable
   As in previous examples, liberal whitespace is used to surround arguments being passed to functions as this is easier on the eyes
5. Practicality – More on conditional evaluation

Before:

              view plain copy to clipboard print ?

         1.    if (!(ret == undefined)) {
         2.        return ret;
         3.    } else{
         4.       return fum('g2g');
         5.    }


After:

              view plain copy to clipboard print ?

         1.    return ret || fum('g2g');


What changed?

   We're no longer relying on the less reliable == (which should really have been === anyway)
   !(ret == undefined) could be rewritten as !(ret) to once again, take advantage of falsy-ness (but this can be further improved)
   Rather than opting for any of the verbose options above, we can take advantage of the fact that in an or expression, ret (if undefined or
   false ) will skip to the next condition and use it instead. This allows us to trim down our 5 lines of code into fewer characters and it's once
   again, a lot more readable
Our final product:

                                                                                                                       converted by Web2PDFConvert.com
             view plain copy to clipboard print ?

       1.     function foo( bar, baz, fum ) {
       2.         var ret,
       3.             out,
       4.             hello = "Hello",
       5.             num = 1,
       6.             i = 0,
       7.             l = bar.length;
       8.         for ( ; i < l; i++ ) {
       9.             out = bar[ i ];
       10.            if ( !out ) {
       11.                 ret = fum( out ) + baz( out );
       12.            }
       13.        }
       14.        return ret || fum('g2g');
       15.    }


Note: I'm aware there is much more that can be done to improve the original code sample. A proper solution would include type checking against bar ,
baz and fum (and more), however for tutorial purposes, I wanted to focus on styling the core concepts.

Recommended JavaScript Beautifiers
Whilst maintaining consistent style while writing your code is extremely important, it can also be useful to use a formatter or beautifier to enforce
style rules for you.

Google Closure Linter
Malte Ubl recently suggested that I try out Google Closure Linter. This set of useful Python scripts first allow us to lint our JavaScript against the
Google JavaScript Style Guide, outputting a list of syntax and semantic changes needed to make our code Style-guide compatible. Users of tools
like jsLint and jsHint will find following the output quite similar to what other linting tools report (line by line errors with the breaking issue reported)
making it quite straight-forward to adjust our code accordingly.

The Closure Linter doesnt just lint code, however. It also includes a script called fixjsstyle which allows us to force (or beautify if you prefer) our
code to follow Google's Style Guide.

Now, it is possible to use both the linter and beautifier scripts independently, but as a Sublime Text user, I would love to be able to simply use
some keyboard shortcuts to lint or beautify my code using Closure Linter as I write it. Thankfully, someone already thought of this and theres a
handy Sublime package available that does just this.

1. To install: Add this repository to Package Control: https://github.com/fbzhong/sublime-closure-linter and install.
2. Restart Sublime Text
3. You should now be able to lint or beautify your code using the following shortcuts:

   1. Run/Execute Closure Linter ctrl+shift+j
   2. Fix JavaScript Style ctrl+alt+shift+j
   3. Show Closure Linter Results in the console
   Note: If you experience issues with paths to the linter tools not being correct, make sure that they have been correctly installed to /usr/bin.
   They may have been pulled into /local/usr/bin instead and you may need to either create a symbolic link to them or copy the files over to
   where the package is attempting to access them from.

jsBeautifier
jsBeautifier is another useful tool which you've most likely heard of before if not currently using at the moment. It accepts everything from
poorly formatted JavaScript to fully minified code, applying a number of spacing/break best practices for making the code more readable. Its
been possible to just use jsBeautifier from the terminal (and the popular jsbeautifier.org website) since it was first released, but similar to
Googles Closure Linter, it would be incredibly helpful to have this available from directly within our text editor.

Luckily, there is also a Sublime Text package for jsBeautifier which can be downloaded from here. Installation just takes a minute.

1. Extract and copy the package to your Sublime packages folder (the relevant path will be the same as the first step in the Closure Linter
   instructions above)
2. Restart Sublime Text
3. You can now beautify your code using ctrl+alt+f


                                                                                                                               converted by Web2PDFConvert.com
Note: You may also be interested in jsFormat – another JavaScript formatting plugin for Sublime which similarly uses jsBeautifier. It's also available on
Package Control and should show up in your install list with no changes.

Code Painter
Whilst the above two beautification tools are helpful for improving readability, what developers really need is a solution thats more flexible.

We might not fully agree with the style guide choices enforced by Google Closure Linter or jsBeautifier. What if we would rather our code followed
Rick Waldrons Idiomatic.js style guide? or the Dojo style guide? or something more custom?. It doesnt really make a great deal of sense to
create new tools for supporting beautification of each individual type of style guide but thankfully there's a tool we can use to solve this problem.

It's a node.js based solution called Code Painter and it allows us to specify a sample JavaScript file following whatever style guide we wish as
input, along with the code we would like beautified. Code Painter will infer the style rules to follow based on the sample and then transform our
input as necessary.

From Jakub Wieczorek, the developer:

Code Painter is useful when you're working on a code change to a project and you want to make sure your new code
fits its style. This could also be integrated with an editor so that it reformats your code as you type based on the style
you've been using so far in a particular file. The solution is essentially a pipeline that consists of a tokenizer based on
Esprima (with a few modifications to preserve comments and whitespaces), then a bunch of different style processors
in the middle (one for each style property) and ends with a serializer that turns the token stream back into source code
(this is a completely lossless process).

At the moment Code Painter only supports transformation of about 7 aspects of code style, but this may be enough for your needs. It
shouldn't take long to see if it's able to handle the specific style rules you would like your project to enforce, so do check it out!

Code Painter can be grabbed from here and used as follows (assuming you already have Node):

          1.    ./bin/codepaint -i myApp.js -s styleSample.js -o myAppStyled.js


Conclusions & Further Tips
   Maintaining a consistent formatting style for your code has a number of advantages, whether you opt to use someone else's style guide or
   your own. Many developers have found it useful to create a personal style guide with what they consider the 'best bits' of numerous others.
   Make effective use of whitespace to aid the readability of what you write.
   Use short, meaningful names for variables, functions and modules. This can help reduce the need for detailed inline comments if it means a
   developer can instantly grasp the purpose of a piece of code.
   Avoid code that is repetitive or can be rewritten to be shorter or more readable. This doesn't necessarily mean forcing everything to use the
   ternary operator or an or condition as we saw in our example. It is perfectly fine to keep code in an extended form, as long as it is easy to
   follow
   Where possible, maintain the principles 'You are not going to need it' (YAGNI) and Keep it short and simple (KISS) when coding. These again
   can help lower verbosity and improve how easy it can be to read what you're written.
That's it. I hope this guide is at least a little useful to someone out there : )

I'm always eager to hear about other takes on this topic or other published style guides. If you would like to contribute to the discussion, feel
free to leave a comment or hit me up on Twitter. Cheers!

Many thanks to Sindre Sorhus for his technical review of this post and many useful suggestions that helped improve it.

   Like          112 likes. Sign Up to see what your friends like.




   May 3, 2012



2 4            C O M M E N T S

               Jack Franklin     May 3, 2012 at 6:02 am                                                                                                              Reply


          Great article as always Addy, however one thing I disagree on in particular moving the counter variable “i” out of the loop. Out of interest, if you were
          writing your own project from scratch, would you abide by this? I don’t particularly see any real advantages to doing this? It just seems to clutter the initial
          var declaration and make it a little less clear that i is used purely for looping.




                                                                                                                                           converted by Web2PDFConvert.com
     Addy       May 3, 2012 at 6:32 am                                                                                                                        Reply


 That’s a very valid point, Jack. I believe James Padolsey also made a similar one on Twitter and I have to say that in my own personal projects, I usually
 *don’t* abide by the idea of moving “i” out of the loop. I would say it’s a stylistic choice at best, but doesn’t exactly kill style if you decide not to move it
 up.
 I guess where it does make sense is if you know you’re highly unlikely to be setting your pointer to anything other than (say, 0) initially and repeatedly
 setting it inline in each loop feels cumbersome or like it doesn’t really add value.
 Other than that, I’m glad you enjoyed the rest of the article!

      Daniel May 3, 2012 at 4:33 pm                                                                                                                           Reply


     I found myself writing pieces of JS that routinely loop within same scope, reusing `ii and `l’. Moving for loops up and down was an annoyance since that
     meant moving “var” part. In that case moving “i, l” up makes sense a lot.
     so the format I found most used by me is:
     var i, l
     for ( i = starting_value_1, l = len_value_1; i < l; i++ ) { … }
     for ( i = starting_value_2, l = len_value_2; i < l; i++ ) { … }
     thus, each of for loops can be moved over each other without me caring about declaration.

     Rick Waldron        May 4, 2012 at 11:21 pm                                                                                                              Reply


 I wrote Idiomatic.js and I abide by that practice in all new projects. JavaScript hoists all initializations to the top – so why not code that way so there’s no
 confusion. Not doing so is as dumb as initializing a variable in the body of an IfStatement.

 PatIbs         May 3, 2012 at 6:17 am                                                                                                                        Reply


Excellent guide Addy. With backbase, we write something like var i, iMax; for (i=0, iMax=checkboxes.length; i < iMax; i++). I see this resembles your POV.
I am happy,
EP

     Chris Heilmann        May 3, 2012 at 9:19 am                                                                                                             Reply


 I also have to say that for ( ; i < l; i++ ) { is not more readable and less cluttered but more of a stumbling block as breaks the previous condition during
 loop condition end condition syntax.
 I started presetting all the counter and loop variables in one statement:
 var i = j = current = 0; or something like that.
 Also, I try to avoid loops that need two variables and when it doesn't matter what order you go through them I normally tend to do a while:
 var i = checkboxes.length;
 while ( i– ) {
 …
 }
 This is very short indeed and works well.

      myfonj        May 3, 2012 at 5:54 pm                                                                                                                    Reply


     I’m sure you and everyone here know that, but to make it clear:
     (function(){ var i = j = current = ‘value’ })();
     defines “j” and “current” variables in the _global_ scope, what is commonly considered harmful.

 Alex_PK         May 3, 2012 at 11:37 am                                                                                                                      Reply


I don’t like your “var” block, because it is very error-prone. Imagine this:
var ret,
out;
hello = “Hello”,
num = 1,
i = 0,
l = bar.length;
Boom! You created 4 global variables instead of 6 local ones. Without errors. Just becausa of a distraction or because you are so used to type ; at the end-
of-line that you do it without thinking.
There are other things I prefer to do differently, but I agree that a style should be decided, adopted and shares within an organization.


                                                                                                                                   converted by Web2PDFConvert.com
   Addy   May 3, 2012 at 11:53 am                                                                                                                          Reply


 My take is that the var block as presented works where a developer is being vigilant. If we were to run the version with the correct commas through say,
 jsHint, as long as the bar variable has been defined previously (which it is as a function argument), everything clears okay. The version with a semicolon
 incorrectly/accidentally placed will however throw errors stating that hello, num etc. are not defined.
 That said, I think you’re right – as long as whatever style is adopted is maintained consistently, a developer or their team should be okay.

   Sindre Sorhus     May 3, 2012 at 12:15 pm                                                                                                               Reply


 That’s why we use strict mode, which will throw a ReferenceError on your example

   Daniel May 3, 2012 at 4:37 pm                                                                                                                           Reply


 Semicolon-less, comma-first style from NPM is perhaps best for this case as it insures there is nothing dangling at the end ever.
 var a
 ,b
 ,c
 ,d

     Rick Waldron     May 4, 2012 at 11:24 pm                                                                                                              Reply


   This is disgusting. You should be ashamed of yourself.

   Rick Waldron     May 4, 2012 at 11:22 pm                                                                                                                Reply


 Dumbest argument ever. Lint your code and this is not a problem.

 Juri May 3, 2012 at 11:48 am                                                                                                                              Reply


What about using double vs single quotes for string litetals?? Would u include that in a styleguide as well??

   Addy   May 3, 2012 at 12:15 pm                                                                                                                          Reply


 You could certainly include that in a style guide (though again, it all comes down to personal preference).

   Sindre Sorhus     May 3, 2012 at 12:19 pm                                                                                                               Reply


 Yes, but there aren’t any best practices. Use whatever you like and stick to it. If working on others code, follow their style. If you’re a team, create a quick
 little style guide. And dont forget; consistency is king.

   Rick Waldron     May 4, 2012 at 11:23 pm                                                                                                                Reply


 All that should be said is that only one quoting style should be used. Mixing is gross and makes your code look amateur.

 Jakub Jankiewicz     May 3, 2012 at 11:54 am                                                                                                              Reply


The only thing I don’t use is this ( foo, bar, baz ) I always use (foo, bar, baz)

 @DuffleDoe      May 3, 2012 at 12:58 pm                                                                                                                   Reply


Interesting, Must agree with Jack, it is not always practical to have variable declaration outside of a loop, however it must be remembered that a code style
expectation is there for a reason and the practical separation of when something is acceptable and when not is often, disconnected from reality. Rather run
with the expectation of what needs to be done according to the style guide. This is a very fundamental philosophy that often cognitively creates an
expectation to do thing according to the “guide”, not leaving any room for misinterpretation of an code style expectation.

 Filip Minev   May 3, 2012 at 3:50 pm                                                                                                                      Reply


Great article, thank you.
I believe my style resembles the most jQuery’s without the extra whitespace. I believe extra whitespace does make the code more readable, however I’m
really not fond of the exceptions they have to this “add-extra-whitespace” rule.
In my opinion, exceptions = confusion = decreased code readability.



                                                                                                                                 converted by Web2PDFConvert.com
            Andrew Cobby        May 3, 2012 at 7:37 pm                                                                                                         Reply


          There are other packages you can get for Sublime Text 2 that can actively lint files you’re working on. Make sure you check out this SublimeLinter package:
          https://github.com/Kronuz/SublimeLinter
          p.s. Any chance you could enhance your comments form with HTML5 form elements? It’s a pain typing email addresses and URLs on iPad/tablets with text
          fields.

             Addy   May 4, 2012 at 5:23 am                                                                                                                     Reply


            Thanks for the additional package suggestion!.
            re: enhancement with form elements, I’ll see what I can do

            steltenpower      May 4, 2012 at 2:33 am                                                                                                           Reply


          Give me “View As” and “Save As” and “quickly build your own style” in editors.
          This way you can always use your own preferred style, without messing it up for others.

            Martin Rinehart      May 4, 2012 at 3:16 pm                                                                                                        Reply


          Good article. It’s a sign of the language’s and the community’s maturity that this has become a topic. Good to see.
          But …
          ….return ret || func(whatever); // horrible code!
          First, only a JS ace can read it. Your maintainer could very well be a Snobol coder dragged in because no one else was available. She doesn’t know JS falsy
          values. You should always write so ANYONE can read your code; never so that only fellow afficionados can read your code.
          Second, logic should be complete before you return a value. You want to be able to stop execution before the return statement, inspect values, (see what
          dumb mistake you made). Almost no debuggers can stop in the middle of an expression. So let’s try again:
          ….if ( ret === undefined ) { ret = func( whatever ); }
          …. // put a breakpoint (or cons.out or …) here, if needed
          ….return ret;


L E A V E                 A       R E P L Y
Required fields are marked *.


Name *



Email *



Website



Message *




 Send



                                                                                                                                                      ← Previous Post




   Follow @addyosmani 23.4K followers




                                                                                                                                      converted by Web2PDFConvert.com
Drag & Drop for WordPress
Arevolutionary new way to build pro sites; faster & easier, than ever before.




                                                                                converted by Web2PDFConvert.com
© AddyOsmani.com




                   converted by Web2PDFConvert.com

								
To top