Following coding standards and naming conventions is an important part of development of high quality JavaScript applications, as long as there is a standard, ideally the source code for the entire project should look as if it was written by a single developer.
Here I am going to present general coding conventions used by JavaScript community and used in open source libraries blogs etc. As a developer, it really helped me to write clean JavaScript code and reducing the common bugs which hard to trace. Here are the standards which I follow.
Indentation:
Without proper indentation it is very difficult to read the JavaScript code tools like Visual Studio, Brackets, etc has indentation rules.
Each indentations level is 4 space ( or 2 space) characters deep.
function showString(inputString) { ....var temp = 10; ....if (inputString === "winter" && temp < 32) { ........alert('cold'); ....} }
Line Length:
Another standard to follow is line length, the maximum line length is 80 characters, if the line goes beyond that , you wrap the line immediately after an operator, such as , +, & etc.
function processRequest( argument1, argument2, argument3, argument4, argument5, argument6) { if (argument1 > 0 &&; argument2 > 0 && argument3 > 0 &&; argument4 > 0 && argument5 > 0 && argument6 > 0) { alert("all args are greater than zero"); } }
Curly Braces:
In JavaScript curly braces are used to group a number of statements. Curly braces should always be used. In the example below, when adding a new line to the if statement you insert it between the braces and it works as expected.
if (true) { alert("yes, true"); }
Without curly braces, It would be easy to add the new line and not realize it would be outside the if statement block.
if (true) alert("yes, true"); alert("really, very true"); // outside the if body
One exception we make to adding curly braces is when the single statement is on the same line. These are short statements but if place it on the next line, braces are required.
if (obj === null) obj = []; for (var i = 0; i < 10; i++) increment(value, i); var Calc = function () { this.add = function (x,y) { return x + y; }; // single line function this.sub = function (x,y) { return x - y; }; };
Opening Braces:
In JavaScript you always place it on the same line, why here is the example.
function processRequest() { // opening brace on same line return { temp: 100 }; }
The reason for this rule is that, JavaScript automatically adds the closing semicolons (;) at the end of each statement that it thinks is missing.
What’s going to happen if i put braces after next line, check this example?
function processRequest() { return { temp: 530 }; }
JavaScript engine changes the above code to the code below and now suddenly your process Request function behaves differently. This can be avoided by moving the opening braces one line up.
function processRequest() { return; // JavaScript added semicolon { temp: 530 }; }
Object literals follow the same curly braces formatting:
var person = { first: "John", last: "Doe", fullName: function () { return first + " " + last; } }
White Space:
Consistent use of white space (the space used between the coding elements) adds to readability and maintainability
Operators such as +, -,=,==,===. &&, || should be surrounded by a space before and a space after to make their expressions easier to read.
var customer = (person.type === "client"); var odd = number % 2 !== 0; if (income > 12000 &&; status === "gold") var found = (hasText &&; (length > 80));
Naming Conventions:
Choosing proper variable and function names is important for readability and general understanding of the code.Variable names are written in camelCase in which first letter is lowercase and the first letters of any subsequent word is uppercase. Try to make the first part of the name as noun (not a verb) which will make it easier to separate it from function names. One example.
var account; var templateHolder = {}; var person = new Person("John");
Make your names as succinct and descriptive as possible. Ambiguity will confuse those that follow you working with the code. Single character names are not descriptive but allowed for iterators.
for (var i = 0; i < 100; i++) { // iterator variables for (var j = 0; j < 100; j++) { sum += i * j; } } var t = (x + y) * fudgeFactor; // temporary variable var rate = t * 3.14 + (t * t);
Use of abbreviated variable names is discouraged, here is the list of commonly used and widely understood abbreviations are acceptable.
Abbreviation | Meaning |
f or fn | function |
cd | code |
l or len | length |
ctx | context |
arg | argument |
obj | object |
el or elem | element |
val | value |
id | identifier |
idx | index |
n or num | number |
ret | return value |
prop | property |
attr | attribute |
prev | previous |
err | error |
dup | duplicate |
doc | document |
win | window |
src | source |
dest | destination |
temp | temporary value |
regex | regular expression |
As we know JavaScript does not have the notation of an access level variables, such as private, protected, public. To indicate that a member (variable or method) is private, JavaScript developers often prefix the name with an underscore _.
var _self; function _locate(customer) { // ... }
Function names are written in camelCase. Frequently they start with a verb. Which separates them from variables as these mostly start with nouns, some function examples.
function processCustomer(customer) { // ... } function calculateRate(amount) { // ... } function add(array) { // ... }
An important convention in JavaScript is that all the constructor functions start with an Upper case character. This is to distinguish them from regular functions and prevents developers from forgetting to add the new keyword before calling the constructor. The problem with forgetting new keyword is that the JavaScript does not flag the error and it causes very hard to detect bugs that may only be found by visually inspecting the code. The upper case name is an important visual cue that the keyword new is required.
function Person(name) { this.name = name; } var arthur = new Person("Arthur");
Abbreviations in function names are discouraged although some common ones are allowed. The list of acceptable abbreviations is the same as the variables names listed before. Function abbreviations you may see are:
Abbreviation | Meaning |
init | initialize |
ctor | constructor |
cb | callback |
Comments
There are two types of comments: single line and multi-line. Single line comments are written with double slashes // and are mostly used as brief hints as to the purpose or inner workings on the code. They can be placed immediately above or after the line of code:
// Ensure membership dues are current and // confirm retiree eligibility (age > 60) for (var i = 0; len = members.length; i < len; i++) { member = members[i]; due = dues[member.payment.id]; // Note: dues are indexed by payment Id // ... }
It is usually best to limit single line comments to 2 or 3 lines at most. If you need more lines, for example explaining a complicated algorithm or piece of logic, then use multiline comments. The preferred format is as follows:
/* * Ensure membership dues are current and * confirm retiree eligibility (age > 60). * Also, the difference between eligible and * ineligibility is determined by their age, * their years of service, their net-worth, * and their marital status. */ function isEligible(person) { // ... }
This format includes asterisks * on each line, vertically aligned to create a clear demarcation of the comment block. Well written comments will significantly add to the readability and maintainability of the code. So what do we mean with ‘well written’? It certainly does not mean extensive or lengthy; in fact, programs that require lengthy comments are probably not written very clearly. You should try to write your code so that it self-documents and that ‘reads like a story’.
You accomplish this with the organization and structure of your files and also with the naming of your objects, functions, properties, variables, and namespaces. Even when your code has been optimized for readability, there are still instances where you need to explain the purpose and/or the inner workings of your algorithms and other code sections.
Comments you write are intended for 2 audiences: 1) for yourself, for when you come back 3 months after writing it, and 2) for your teammates who have never seen your code before and who will need to quickly locate and correct a problem (bug) in your program. Here are some guidelines for good comments. First: avoid the obvious.
// iterate over each person for (var i = 0, len = persons.length; i < len; i++) { person = persons[i]; // ... }
As a programmer you know that a for-statement does looping. You see a persons array so that is what you are iterating over. This comment does not add any value; in fact it distracts the reader.
It is very important to update your comments when the code changes. There is nothing worse than comments that are outdated, incorrect, or invalid. Better to have no comments at all.
When a program is well structured and well written (i.e. it flows like a story), most developers will be able to relatively quickly see what is happening at a particular location in the code. After studying it for a while it may be clear what is happening, but what may not be obvious is why it is done; essentially what is the purpose.
Suppose you have an array of customers. You see that the program checks for each customer how long they have been doing business with your company and then some begin and end dates that are compared against the current date. Based on this evaluation some customer’s creditworthiness is upgraded. You see what is does, but you wonder what it means. It turns out that the company is running a special during a limited period in which certain customers are given special rates. It is important that this is explained in the comments because by just looking at the code it is not obvious this is a temporary sales offer.
Furthermore, the explanation that this is a sales special is not really sufficient. The rules of the offer (i.e. the algorithm used) also need clarification. The above example is not very complex, but sometimes the rules for sales offers can get very complicated, so the logic needs to be documented.
Finally, if you need API documentation of your programs (for internal or external users) then use a tool that auto generates it from specially formatted comments in your code. The two most popular tools are YUIDoc and JSDoc-Toolkit. Both are open source and can be downloaded for free.
Before running the documentation tool you decorate all (public) functions with a multi-line comment box which follows a special syntax which including special tags that are prefixed with a @. The output is nicely formatted documentation in the form of a series of HTML pages that you then can publish. Here is an example of the comment syntax:
/** * Invoke a method on each item in the array * * @param {Array} array The array to iterate over. * @param {Function} method The method to invoke. */ function invoke(array, method) { }
Variable declarations :
All variables should be declared before being used or else they end up in the global namespace. The JavaScript engine hoists (raises) all variable declarations to the top of the function in which they are declared. This can lead to hard-to-detect problems where variables are being used before they are initialized. Here is a simple example. As expected the code below displays 10 (two times);
function doSomething() { var index = 10; alert(index); // =>; 10 alert(index); // =>; 10 } doSomething ();
Next we move the variable declaration and initialization one line lower. This results in the index being undefined and later it is 10.
function doSomething() { alert(index); // =>; undefined var index = 10; alert(index); // =>; 10 } doSomething();
What JavaScript does it hoists the variable declaration to the top, but not the initialization. The code that actually executes looks like this:
function doSomething() { var index; alert(index); // =>; undefined index = 10; alert(index); // =>; 10 }
It gets even weirder when you also have a global variable named index:
var index = 9; function doSomething() { alert(index); // =>; undefined var index = 10; alert(index); // =>; 10 } doSomething();
You would expect that the first alert would print 9 because index gets only shadowed by the local index variable in the next line. But this is not the case, again due to the hoisting that takes place the code that executes looks like this:
var index = 9; function doSomething() { var index; alert(index); // =>; undefined index = 10; alert(index); // =>; 10 }
What gets displayed in the first alert is the local index variable, not the global version.
Single var pattern :
to avoid the above problems you should declare and optionally initialize all variables at the beginning of a function. This is a well-known coding pattern in JavaScript and is named the Single var pattern. A single var is used to declare all variables used in the function. Here is an example of how this is commonly done:
function func(arg1, arg2, arg3) { var index, textFormat, count = 0, person = new Person("Hillary"); // ... }
The issue of variable declaration is one of those issues where developers can get into heated debates. Some will argue that the above example is not structured enough: they would prefer this:
function func(arg1, arg2, arg3) { var count = 0, person = new Person("Hillary"), index, textFormat; // ... }
Each variable has its own line. The initialized variables are listed first, followed by the ones that are not initialized. Also notice how the = signs of the initializations are vertically aligned.
If these rules work for your team you should adopt these. In our own work we are a little less strict and have adopted a few exceptions to the single var pattern.
First, it may be helpful to group variable declarations with each group having its own var, like so:
(function () { var win = window, doc = document, nav = navigator; var userAgent = nav.userAgent, isIE = /msie/t.text(userAgent) && !win.opera, isFirefox = /Firefox/.text(userAgent), isWebKit = /AppleWebKit/.test(userAgent), hasTouch = doc.documentElement.ontouchstart !== "undefined"; // ... }());
We also allow multiple uninitialized variables on a line, like so. However, initialized variables are best kept on their own line:
function (employees) { var type, index, element, option, person = new Person("Annie"), employeeCount = employees.length; // ... }
It turns out that the single-var pattern is rather error prone. If you accidentally terminate a line with a semicolon (a common mistake), then all subsequent variables become global which is highly undesirable.
function (employees) { var type, person = new Person("Annie"); employeeCount = employees.length; // global! // ... }
Some JavaScript developers move the comma forward, to better see that each line has a comma.
function (employees) { var type , person = new Person("Annie") , employeeCount = employees.length; // ... }
A consequence of enforcing the single var rule is that iterator variables (like, i, j, k or count) also end up being declared and initialized at the beginning of the function. Here is an example:
function func(arr) { var count = 10, i = 0, len = arr.length; for (; i < len; i++) { // .. } }
However, this does not feel right; the for-loop seems incomplete and unnatural. Our approach is to allow the var in the for statements where they are used. This way the declarations and their initialization are right there (‘in your face’ so to speak), close to where they are used. In summary, we prefer this:
function func(arr) { var count = 10; for (var i = 0, len = arr.length; i < len; i++) { // .. } }
Function declarations:
just like variables, methods are hoisted and should be declared before they are used. Within a function it is best to declare functions immediately following the variable declarations.
function func(arr) { var count, element, status; // immediately declare methods var inner1 = function () { /* ... */ }; var inner2 = function () { /* ... */ }; // ... }