NML

Javascript guidelines

General JavaScript Principles

  • 99% of JavaScript should be included in external JavaScript files and included at the END of the BODY tag. One exception to this rule is Modernizr which should be included at the end of the <head>.
  • Feature detect, don't browser detect. Modernizr is a great resource for doing this.
  • Name variables and functions logically and in camelCase. Sensible names that are long are preferred to short names that make no sense.
  • Try to write functions to follow the principle that they should do one thing and do it well. If you can see that a function is becoming more complex, abstract it out into multiple functions – it will become more readable, reusable and will make more sense to someone unfamiliar to the code.
  • Prefix jQuery collection variables with the dollar ($) character e.g $headerChildren
  • Class declarations should start with a capital letter.
  • Constants or configuration variables should be at the start of a class and written in CAPS.
  • Build using the object literal pattern e.g.
var SiteSetup = {
init: function () {
this.$sections = $('#container section');
this.$additionalTextNodes = $('section a > span');
this.createMarkup();
},
createMarkup: function(){
var $additionalTextNodes = this.$sections.remove();
&additionalTextNodes.css({
position: 'absolute',
top: this.style.left - $sections[0].style.width / 2
});
}
}
SiteSetup.init();
  • Structure and formatting should follow the example below:

$(function(){

var SiteSetup = {
ANIMATION_SPEED: 100,

init : function () {
//fire off all other classes
if (LightBox.$lightbox.length > 0) {
LightBox.init();
}
}
},
LightBox = {
$lightbox: $('.lightbox'),

init : function () {},
open : function () {},
close : function () {}
};

SiteSetup.init();
});
  • Documentation should follow NaturalDocs structure. As with all code, document as frequently as you can - the more detail the better. At the very least, document each function you create.

Read: The Essentials of Writing High Quality JavaScript

Formatting and code sensibility

  • Separate operators/comparators with spacing
// Good
if (foo && foo.bar && typeof foo.bar === 'object') {
foo.bar.call();
}

// Terrible
if(foo&&foo.bar&&typeof foo.bar==='object'){
foo.bar.call();
}
  • Use braces for logic evaluations. If evaluation execution is simple, keep non-braced logic on a single line e.g:
// Good
if (i < 10) return true;

// Good
if(foo && foo.bar && foo.bar > 10) {
foo.baz = foo.bar - 100 * 2.7 + 'rad'
}

// Bad
if(foo && foo.bar && foo.bar > 10)
foo.baz = foo.bar - 100 * 2.7 + 'rad'

// Bad
if(i < 10)
return true;

// Bad
if(i < 10)
{
return true;
}
  • Remap this to self when passing context
  • Always use === as a comparator (unless you really need flexible evaluations e.g comparison to null)
  • Always add a second radix param to parseInt() to prevent accidental octal issues
  • Never bother comparing variables to true/false
  • For large loops, either cache the length variable to prevent re-evaluation or use a reverse while loop
  • Don't create functions in loops - it's slow
  • When creating functions with many parameters, pass in an object rather than listing numerous parameters.
    • use $.extend if you are using jQuery to extend a passed in object while providing defaults

Libraries

When considering how we use JavaScript on a project, no two projects are usually the same in how it uses libraries, although the style and inclusion of the libraries is kept as consistent as possible.

Many of our projects are developed using a mix of native JavaScript and jQuery, although the use of jQuery or simply a native solution is considered at the start of each project.

Plugins

Use plugins with caution. Often they are overkill. If plugins are indispensable make sure they are actively maintained and of high quality..

Dependency Management

Nothing yet

jQuery Best Practices

  • Always cache DOM selection if you plan to re-use data
  • Use efficient query selectors. Write for many browsers, don't assume document.querySelector()
  • Avoid using $.each for repeated or performance critical functionality. Instead use a for or reverse while loop (especially for large objects)
  • Use on() and off() handlers for events. Everything else is now deprecated (live, delegate, bind)
  • When using simple html5 attribute data, simply use $selected.attr('data-foo') unless working with complex data types (where you can use $selected.data())
  • Try to understand the underlying JavaScript functionality of jQuery methods. This will help you write much more efficient selectors (watch Paul Irish's talk - 10 Things I Learned from the jQuery Source)

Debugging

Browser tools can save you hours in debugging.

Use console.log() instead of alert(), or Paul Irish's lightweight wrapper