Best Practices
Here are a few Best Practices to follow when coding in JavaScript.
White Space
Follow these recommendations so commits and diffs will be easier to read.
- Do not mix spaces and tabs.
- Configure the editor to “show invisibles”. For example, in Sublime Text, the setting is
"draw_white_space": "all"
. - Configure the editor to remove end of line whitespace.
- Choose one, spaces or tab indentation for all JavaScript the team is writing for the project. Consider this, a space is always just one column. The code editor setup pages linked below have info on how to configure for consistent formatting of tabs to spaces and vice versa.
- Use a consistent value throughout the project for the indent size, e.g., 4 columns.
Code Editor Setup
Sublime Text
Configure for JavaScript
Comparison Operators
Use ===
and !==
The equality operator ==
implicitly tries to convert the values before comparing. The identity or “strict equals” operator ===
does not convert the values when comparing. Use the equality operator ==
and !=
only as needed.
Semicolons
Include all necessary semicolons. Configure your editor to use JSHint, a fork of JSLint, used to detect errors and potential problems in JavaScript.
Global Scope
Any variable that is defined outside of a function body is global in scope. Global variables can be accessed and altered in any scope. Global variables should be declared only as needed. For more information, read this YUI blog post.
Namespace
Using a namespace is a good practice to keep your code out of the global scope.
// global scope without a namespace
var foo = 'bar';
// namespace example
var app = {};
app.foo = 'bar';
// even better,
// namespace check before creation example
var app = app || {};
Line Length
80 characters per line should be sufficient enough to work with. When a statement will not fit on a single line, it may be necessary to break it. Place the break after an operator, ideally after a comma.
Eval
As Douglas Crockford states in his Code Conventions for the JavaScript Programming Language, “eval is Evil”. Improper use of eval makes your code unsafe and difficult to debug.
Curly Braces
For consistency and potential error prevention if additional statements are ever needed in the future, wrap them in curly braces. Minification will remove curly braces as needed for production.
// valid but not recommended
if (condition)
alert('Condition true');
else
alert('Condition false');
// recommended
if (condition) {
alert('Condition true');
}
else {
alert('Condition false');
}
Quotes
Use single quotes so strings containing double quotes don’t need to be escaped.
Arrays
Creating arrays should be done using the shorthand [] constructor instead of using new Array() notation.
// valid but not recommended
var city = new Array('Atlanta', 'Boston', 'Cleveland');
// recommended
var city = ['Atlanta', 'Boston', 'Cleveland'];
Objects
Object literal notation is recommended unless the object requires a specific prototype, then create the object by calling a constructor function with new.
// object literal notation
var config = {};
// constructor function with new
var cityGallery = new Gallery();
Object properties should be accessed using dot notation, unless the key is a variable, a reserved word, or a string that would not be a valid identifier.
prop = obj.propertyName;
prop = obj[variableKey];
prop = obj['default'];
prop = obj['key-with-hyphens'];
Script Element
The <script src="filename.js"></script>
element or script tag as it is often referred to should be placed as far down in the body as possible. Ideally, just before the closing </body>
tag. Some browsers try to load script files when they hit the script tag and the rest of the page is not parsed until script loading has finished. Additionally, async and defer attributes can be used to control when requested scripts are loaded.
async
downloads the file during HTML parsing. The HTML parser will pause to execute the script when the download is completed.
defer
downloads the file during HTML parsing. The script will execute after the HTML parser has completed. Multiple defer scripts execute in the order they appear in the document.
More info is available from this developers.google.com resource, Parser blocking versus asynchronous JavaScript
Miscellaneous
// object functions
app = {
square: function( number ) {
return number * number;
},
double: function( number ) {
return number + number;
}
};