Jump to: navigation, search

Difference between revisions of "Horizon/Javascript"

(Required:)
(Required:)
Line 10: Line 10:
 
Before committing your code, please review the following checklists of Dos and Don't-Dos. Though we all have our preferences, these are the most commonly accepted rules.  
 
Before committing your code, please review the following checklists of Dos and Don't-Dos. Though we all have our preferences, these are the most commonly accepted rules.  
  
'''Best Practices "Do's" Checklist'''  -
+
'''Reliable'''  -
* ''Give meaningful names to methods and variables''
 
 
 
* ''Put a comment at top of every file'' explaining what the purpose of this file is.  This rule also applies to methods and variables when the naming is not obvious.     
 
  
 
*  ''Use '===' as oppose to '==' for equality checks''.  The '==' will do a type cast before comparing, which can lead to unwanted results.   
 
*  ''Use '===' as oppose to '==' for equality checks''.  The '==' will do a type cast before comparing, which can lead to unwanted results.   
Line 35: Line 32:
  
 
   
 
   
'''Best Practices "Don't Do" Checklist''' -
 
 
* ''Do not put variables or functions in the global namespace''.  There are several reasons why globals are bad, one being that all JavaScript included in an application runs in the same scope.  Which means that if another script has the same method or variable names they overwrite each.
 
* ''Do not put variables or functions in the global namespace''.  There are several reasons why globals are bad, one being that all JavaScript included in an application runs in the same scope.  Which means that if another script has the same method or variable names they overwrite each.
  
Line 44: Line 40:
 
* ''Avoid using with()''.  The with() method is used to access properties of an object.  The issue with 'with' is that its execution is not consistent, so by reading the statement in the code it is not always clear how it is being used.
 
* ''Avoid using with()''.  The with() method is used to access properties of an object.  The issue with 'with' is that its execution is not consistent, so by reading the statement in the code it is not always clear how it is being used.
  
* ''Avoid excessive nesting''.  This and the rest of the items in this list is to keep the code more reader friendly and maintainable (and are self explanatory).
+
'''Readable & Maintainable'''
 +
 
 +
* ''Give meaningful names to methods and variables''
 +
 
 +
* ''Put a comment at top of every file'' explaining what the purpose of this file is.  This rule also applies to methods and variables when the naming is not obvious.
 +
 
 +
* ''Avoid excessive nesting''.
  
 
* ''Avoid excessive function chaining''.  The key here is 'excessive', there is nothing wrong with chaining functions calls just don't over do it.  Note:  The exception is AngularJS where function chaining is utilized quite a bit.
 
* ''Avoid excessive function chaining''.  The key here is 'excessive', there is nothing wrong with chaining functions calls just don't over do it.  Note:  The exception is AngularJS where function chaining is utilized quite a bit.

Revision as of 18:29, 26 August 2014

****** Under Construction ******

Code Style Guidelines

As a project, Horizon adheres to code quality standards. To that end we listed out coding standards and best practices for the different clientside languages used in Horizon divided into Required and Recommended sections. Our main goal in establishing these best practices is to have code that is readable, maintainable, and reliable.

JavaScript

Required:

Before committing your code, please review the following checklists of Dos and Don't-Dos. Though we all have our preferences, these are the most commonly accepted rules.

Reliable -

  • Use '===' as oppose to '==' for equality checks. The '==' will do a type cast before comparing, which can lead to unwanted results.
  • Keep document reflows to a minimum. DOM manipulation is expensive, and can become a performance issue. Make sure that if you are accessing the DOM that you are doing it in the most optimized way. One example is to build up document fragments and then append the fragment to the DOM vs do multiple smaller DOM updates.
  • Use “strict”, enclosing each JS file inside a self-executing function." The self-executing function keeps the strict scoped to the file, so its variables and methods are not exposed to other JS files in the product. Note: By using strict in your JavaScript exceptions will be thrown for common coding errors, like accessing global vars, that normally are not flagged.
    Example: (function(){
                'use strict'; 
                 // code...
              })();
  • Use for each when looping whenever possible. AngularJS, and jQuery both provide for each loops that provide both iteration and scope. If you have to use JavaScript for loops make sure they are optimized. A couple examples are:
  1. Checking array length on each iteration of loop.  Instead save the array length to a variable, as in the for loop on the right.

         for(var i=0;i<my_array.length;i++) {                            for(var i=0,j=my_array.length;i<j;i++) {
           x = my_array[i];                                                x = my_array[i];
         }                                                               }

  2. No DOM insertions inside a for loop.   It's ok to create DOM nodes inside the loop, but wait to insert until after the loop.


  • Do not put variables or functions in the global namespace. There are several reasons why globals are bad, one being that all JavaScript included in an application runs in the same scope. Which means that if another script has the same method or variable names they overwrite each.
  • Always put var in from of your variables. (Not putting var in front of a variable puts that variable into the global space) But as mentioned above, global variables in general are bad, so unless you have specific reason to have a global variable look for an alternative.
  • Avoid using eval( ). The eval () just does that, it evaluates the expression passed to it. This can open up your code to security vulnerabilities, and other issues. I know some will argue that using eval is not always dangerous, but this is a best practice document after all. In most cases there is a viable alternative, use it.
  • Avoid using with(). The with() method is used to access properties of an object. The issue with 'with' is that its execution is not consistent, so by reading the statement in the code it is not always clear how it is being used.

Readable & Maintainable

  • Give meaningful names to methods and variables
  • Put a comment at top of every file explaining what the purpose of this file is. This rule also applies to methods and variables when the naming is not obvious.
  • Avoid excessive nesting.
  • Avoid excessive function chaining. The key here is 'excessive', there is nothing wrong with chaining functions calls just don't over do it. Note: The exception is AngularJS where function chaining is utilized quite a bit.
  • Avoid HTML and CSS in JS code. HTML and CSS belong in templates and stylesheets respectively. For example:
  1. In our HTML file, we should focus on layout.
     i. Reduce the small/random <script> and <style> elements in HTML.
     ii. Avoid in-lining styles into element in HTML. Use attributes and classes instead
  2. In our JS files, we should focus on logic rather than attempting to manipulate/style elements. 
     i. Something like element.css({property1,property2...}) belongs in a CSS class.
     ii. Something like $("<div><span>abc</span></div>") belongs in a HTML template file. Use show/hide/clone elements if dynamic
         content is required.
     iii. Avoid using classes for detection purposes only, instead, defer to attributes.  For example to find a div: 
         <div class="something"></div> 
          $(".something").html("Don't find me this way!");
          
         Is better found like: 
           <div data-something></div> 
            $("div[data-something]").html("You found me correctly!");
  • No commented-out code.
  • Remove dead code.


Keeping the above checklist's in mind is just good practice and will help you become a better JavaScript programmer. But what if you can't find the best practices URL or just forget to check all your files or one of the practices. (Not to mention all of the common errors like forgetting a semi-colon or comma.) That is where JSHint comes in.

JSHint is a great tool to be used during your code editing to improve JavaScript quality by checking your code against a configurable list of checks. Therefore, JavaScript developers should configure their editors to use JSHint to warn them of any such errors so they can be addressed. JSHint has a ton of configuration options to choose from, the good news is we widdled down the list to the options Horizon wants enforced and provided instructions for setting it up JSHint for Eclipse, Sublime Text, Notepad++ and WebStorm/PyCharm are provided.

Recommended:

Source-code formatting – (or “beautification”) is recommend but should be used with caution. Keep in mind that if you reformat an entire file that was not previously formatted the same way, it will mess up the diff during the code review. It is best to use a formatter when you are working on a new file by yourself, or with others who are using the same formatter. You can also choose to format a selected portion of a file only. Instructions for setting up JSHint for Eclipse, Sublime Text, Notepad++ and WebStorm/PyCharm are provided.

Use { } for if, for, while statements, and don't combine them on one line for code maintainability / readability.

// Do this          //Not this          // Not this
if(x) {             if(x)               if(x) y =x;
   y=x;                y=x;                          
}

AngularJS

Required:

  • Organization: Define your angular app under the root angular folder (such horizon/static/horizon/js/angular/hz.table.js). If you're application is small enough can choose to lump your Controllers, Directives, Filters, etc.. all in the one file. But if you find your file is growing to large and readability is becoming an issue, consider moving function into their own files under sub folders such as (horizon/static/horizon/js/angular/directives/hz.table.directives.js).
  • Separate presentation and business logic.
  • Controllers and Services should not contain DOM references. Directives do.
  • Controllers have view behaviors
  • Services are singletons and contain logic independent of view
  • Scope is not the model (model is your JavaScript Objects), the scope references the model.
  1. Read-only in templates,
  2. Write-only in controllers

Recommended:

  • Since Django already uses {{ }}, use {$ $} instead or {% verbatim %}
  • Don't use variables like "app" that are at the highest level in the file, when Angular gives an alternative. For example use function chaining.
  • Put "Ctrl" on the end of a controller file name
  • Use these directories: filters, directives, controllers, and templates. Note: When you use the directory name, the file name does not have to include words like "directive" or "filter".
  • For localization of AngularJS templates in horizon, there are a couple of ways to do it.
  1. Using gettext or ngettext function that is pass from server to client. However, this depends on the catalog object that is also pass from server to client. If you're only translating a few things, this methodology is ok to use.
  2. Use an angular directive that will fetch a django template instead of a static HTML file. The advantage here is that you can now use {% trans %} and anything else Django has to offer. You can also cache the page according to the locale if you know the content is static.