WWF-UK Javascript Style guide
This document draws heavily from the following guides written by smarter people than me:
- https://google.github.io/styleguide/jsguide.html
- http://javascript.crockford.com/code.html
- https://github.com/airbnb/javascript
It should be considered as both draft and canonical. Draft because I'm open to a debate on the practices defined. Canonical because in the absence of that debate the guidance here should be reflected in your code.
tl;dr
- Use .js files
- "use strict"
- Use jshint
- Use camelCaseVariableNamesIcanUnderstand
- Avoid global variables
- Do not use
eval
- Do Use
===
Javascript Files
Use them for anything other than short snippets or code that is specific to that particular page view. They can be loaded in parallel miniifed and cached. It also makes it easier to lint your code.
Strict mode
Adding "use strict"
to the start of a function tells the browser to use strict mode. This will make the browser fussier with you code - more errors reported = more predictable code. For example this code will give you "Uncaught ReferenceError: watsInTheTin is not defined" with strict mode but without it you'll just be wondering where your sausages went.
function foo() {
var whatsInTheTin = 'beans';
whatsInTheTin = whatsInTheTin + ' and sausages';
return whatsInTheTin;
}
Spacings
Spaces around =
, +
, and -
etc makes things more readable:
function foo() {
var something = 1,
somethingElse = 1 + (2 * something);
}
Indentation
Spaces. Multiples of four.
Line Length
Try to keep lines under about 80 character. Here are some strategies:
Long strings should be built like this:
var pandaIntro = 'This charismatic and universally-loved species – the' +
'symbol of our organisation – is one of the rarest and most' +
'endangered bears in the world.';
Methods should be chained like this:
$('.pandas')
.find('.wild-pandas')
.count()
.countAgain()
.addToSurvey()
.end()
.find('.baby-pandas')
.count()
.countAgain()
.addToSurvey();
Function arguments
Should normally be on one line but if they are very long (which they should be if it helps understand their purpose) then use one per line like so:
function foo(
veryClearlyDescribedArgument,
anotherEasilyUnderstoodArgument,
thisOneIsVeryLongToo) {
//...
}
Comments
Comment well, but don't feel the need to over-explain. We all know what var i=0;
does. Use the prefixes //FIXME
and //TODO
where appropriate.
Variables
Variable names should err on the long and descriptive side. Use camelCaseToSeparate words (in contrast, filenames should be all lowercase and css classes should be separated by hyphens ).
Use global variables sparingly. Declare variables at the start of functions with a separate var
statement for each to aid readability. Start with assigned variables. Use CAPS for constant values (But note that javascript has no real constants). Use $
as a prefix when you're caching jQuery representations of the DOM object (which is a good idea).
Only use let
and const
in JavaScript that's going to be transpiled; don't use either in production code.
var pandas = getPandas();
var $partOfTheDOMImGonnaMessWith = $("#very-important-button");
var TAU = Math.PI*2;
var angleOfPandaUrinatingUpATree;
Semicolons
Use them. I'm very good at forgetting too. JSHint is very good at reminding me.
if...
if
statements always get their brackets and braces for clarity. For example:
if (condition){
// statements
} else if {
// statements
} else {
// statements
}
Use the ternary operator for simple conditional assignments as long as your code is still readable.
msg = score > 100 ? 'Great score' : 'Nice try!'
If you're considering breaking a ternary operator out into separate lines for readability then an old fashioned if (valueWeHave === valueWeWant){}
is more readble IMHO.
eval()
Don't use it.
Equals or not
Use ===
and !==
Object and Array Literals
Use them for defining new objects and arrays eg objFoo={foo:'baa'}
or arrCountMeIn=[5,6,7,8]
rather than new Object()
or new Array()
Date()
The Date() function accepts input in two forms:
- A list of integers eg: Date(2016,02,19,20,30) NOTE month is zero indexed so 0 = Jan, 1 = Feb, 2 = March
- A date formatted string, Different browsers support different string formats, however the ECMA standard (http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 )is of the form 2016-03-19T20:30:00.000Z
Preference in our javascript should be to use the first form. If the second method is used it should be with the above standard to avoid cross browser compatibility issues.