Javascript Coding Standards

Best Practices:

1.       Use hosted JavaScript libraries, such as Google CDN. Using hosted JavaScript libraries lowers bandwidth costs and often reduces page load time through browser caching. Also, JavaScript hosted on another domain will be allowed to download in parallel with other resources.
  1. Include JavaScript at the bottom of HTML documents whenever possible.
  2. Minify JavaScript.

Why is consistent code style important?

1.       Consistent code, even when written by a team, should look like one person wrote it.
  1. Following a consistent style guide helps improve the overall quality of the code we write. This helps other developers stepping in to assist with maintenance more easily and can certainly save time in the long haul.
  2. Readable source code is arguably easier to understand as well. It's easier to browse, locate and fix bugs in, and easier to optimize. It can also give us a clearer picture of how the code fits into a larger body of work.

Consistently styled code can:

1.       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.
  1. Our JavaScript style should always pass JSLint/JSHint with no options to turn certain checks off.

Whitespace:

1.       Always use two spaces.
  1. Never use tabs.
  2. Never leave trailing whitespace.
  3. Put whitespace between operators.
  4. Most importantly, make it look good.
  5. Readable code is better than code smashed into one line. Let the minifier shorten the code up.
  6. You are writing code for a person to read, not a machine. Stupid slow code is better than clever fast code.
  7. We care more about beautiful code than fast and clever code.



OK
if (foo === bar) {
x = y + 7;
x += 2;
}
var query =
foo. Find()
.limit()
.sort();


NOT OK
if(foo == bar){
x = y+7;
x+=2;
}
var query = foo. Find().sort().exec();

Strict Mode:
Every java script file should start with "use strict";
For this project,  do not do this. "use strict"; will be automatically added during the build step.

Semicolons:
Use semicolons. That is all. Ignore the nay-Sayers. They are wrong. JSHint will enforce this.

Quotes:
Prefer 'single quotes' over "double quotes". Always.

Arrays:
Use [1, 2, 3] instead of new Array (1, 2, 3).

jQuery events:
When using jQuery, always us the "on" event binding syntax.


OK
$('.mySelector').on('click', function() {
});


Not OK
$('.mySelector').click(function() {
});

Delegate the click handles as much as makes sense. Not everything should be delegated to $('body'), but not everything should be handled by the element either.

OK
// Case 1
$("div#target span.green").on ("click", function () {...});


Better
// Case 2
$("div#target").on ("click", "span.green", function () {...});

Summary:

1.       In case 1, each of those spans has been individually given instructions. If new spans get created, they won't have heard the instruction and won't respond to clicks. Each span is directly responsible for its own events.
  1. In case 2, only the container has been given the instruction; it is responsible for noticing clicks on behalf of its child elements. The work of catching events has been delegated.

jQuery variables:

When assigning the results of a jQuery selector to a variable, always prepend that variable with a "$" so that it is obvious later on that you are working with a jQuery object.


OK
var $myElement = $('.mySelector');
$myElement.fadeIn();


Not OK
var myElement = $('.mySelector');
myElement.fadeIn();

Curly Braces:

1.          You should always use curly braces, with the exception of if (err) return next (err); in a node environment.
2.          Braces should always be on the same line as the control statement.
3.          There should always be whitespace around braces.


OK
if (foo) {
bar();
} else if (baz) {
bam();
} else {
fish();
}
if (meow) {
mix();
}
function foo(bar) {
return bar + 'bar';
}


Not OK
if (foo) bar();
else if (baz)
{
bam();
}
else
fish();
if (meow) // always remember your braces
mix();
if (moew) {// <----- IF THERE ISN'T A SPACE, SCOTT WILL SUFFER FROM SERIOUS OCD. YOU DON'T WANT THAT, DO YOU???
mix();
}
function foo ( bar ){
return 'this is really bad style'
}

Variable declarations:

1.       Always use camel Case.
  1. Do not use underscore separated or CONSTANT_NOTATION variable names.
  2. Do not start variables with a capital letter unless they are a class declaration or an Angular module (such as App, Controllers, Directives...etc.);
  3. In config files, keys should be underscore separated. They should not use dashes or capital letters.
  4. In a node environment, uses good ordering with require statements. Put built-in modules first, then npm modules, then relative requires.
  5. When declaring variable list use the following syntax, of putting the comma at the end of the line. Always align on the '=' sign.
  6. Even though these examples are in a node environment, this pattern still stands for normal browser JavaScript as well.



OK
var fs = require('fs'),
express = require('express'),
redis = require('redis'),
config = require('config'),
models = require('models'),
baptize = require('lib/baptize'),
calculator = require ('.../lib/calculator'),
app = express.createServer(),
appCache = {};


Not OK
var express = require('express')
, redis = require('redis')
, models = require('models')
, fs = require('fs') // this should be first
, calculator = require ('.../lib/calculator')
, config = require('config')
, app = require('express').createServer() // requires should be by themselves
, app_cache = {};

Functions:

Methods should be declared as functions, and not assigned to vars. Call-backs should be called cb, and should be the last argument

OK
function doublePositive(number, cb) {
// when possible, handle error cases first
if (number <= 0) return cb(new Error("number not positive"));
cb(null, number * 2);
}


Not OK
// anonymous functions result in bad stack traces
var doublePositive = function(number, call back) {
if (number > 0) {
// a non-error should be null
call back(false, number * 2);
} else {
// do not return strings for error param
call back("number not positive");
}
}

Objects:

1.       Always use comma last formatting.
  1. If an object has only one property, inline it, and put spaces after and before the braces.
  2. If an object has multiple properties, put each property on its own line.
  3. If all object keys are valid identifiers, then do not use quotes. If any object key is not a valid identifier, all keys must have quotes.



OK
var conf = { put: 'spaces' };
var user = {
name: {
first: 'John',
last: 'Doe'
},
email: 'john@doe.com'
};
var headers = {
'Content-Type': 'text/plain',
'Content-Length': 1024,
'Connection': 'close'
};


NOT OK:
var conf = {'put’: ‘spaces'};
var user = {
"name": { "first": 'John', "last": 'Doe' },
"email": 'john@doe.com'
};
var headers = {
"Content-Type": 'text/plain'
, "Content-Length": 1024
, Connection: 'close'
};

Logging:
Log all you want. console.log statements will be removed during the deploy step.

Iteration:
For consistency in the browser, use lodash for the great iterator functions it provides.

Type Co-ersion:
Always be explicit in showing when casting to a type.


OK
x = present(x);
x = parseFloat(x);
x = Number(x);
x = Math. Floor(x);
x = x.toString();
x = Boolean(x);


Not OK
x = +x;
x = new Number(x);
x = x+'';
x =!!x;

Type Testing:

1.       When testing for truthiness/existence, use if (variable) or if (! variable). This takes care of cases where "variable" is undefined, an empty string, or anything else in JavaScript that is "falsely".
2.       If looking for a specific type, use typeof.
3.       Test for Arrays with Array.isArray or arr instance of Array.

OK
if (!(arr instance of Array)) {
arr = [];
}
if (!Array.isArray(arr)) {
arr = [];
}
// if it should be either an array or falsely, then this is better.
if (!arr) {
arr = [];
}
// or
arr = arr || [];
if (err) return cb(err);
if (!arg) {
arg = 7;
}


NOT OK
if (_.isArray(arr))
{
arr = [ ];
}
if (typeof err === 'object' && err !== null) return cb(err);
if (arg === null || arg === undefined || arg === false) {
arg = 7;
}


No comments:

Post a Comment