JavaScript Style Guide

JavaScript syntax and coding best practices with examples.

Scroll down...

Content

Resources

Comments

The purpose of this style guide is to promote consistency in the appearance and behavior of your JavaScript code.

Variable

Always declare variables with the var keyword, otherwise, you are declaring a variable in the global namespace.

// bad
myVar = 'foo';

// good
var myVar = 'foo';

Always use camelCase for variable names

// bad
var my_var = 'asdf';

// good
var myVar = 'asdf';

Constants

Always use UPPER_SNAKE_CASE for constants.

// bad
var My_Constant = 'bar';

// good
var MY_CONSTANT = 'bar';

Semicolons

In general, always use semicolons to terminate statements. Never omit semicolons in favor of relying on Automatic Semicolon Insertion. It is a bad practice.

// bad
function getValue() {
  return 'Omit the semicolon?!'
}

// good
function getValue() {
  return 'But I love semicolons!';
}

Always use semicolons after variable declarations.

// bad
var foo = 'asdf'

var x = {
  foo: 'bar'
}

var x = [
  'asdf',
  'fdsa'
]

// good
var foo = 'asdf'; // <<<<

var x = {
  foo: 'bar'
}; // <<<<

var x = [
  'asdf',
  'fdsa'
]; // <<<<

Including when the variable is a function

// bad
var foo = function() {
  console.log('Hi!')
}

// good
var foo = function() {
  console.log('Hi!'); // <<<<
}; // <<<<

No semicolon is needed when creating a named function.

// bad
function foo() {
  console.log('Why did you put a semicolon after this function?');
};

// good
function foo() {
  console.log('No semicolon after this function!'); // <<<<
}

Semicolons are needed when assigning a function to a variable.

// bad
var func = function(str) {
  return str + ' Hello!';
}

// good
var func = function(str) {
  return str + 'Hello!';
};

Functions

There are a few different ways to define functions in JavaScript. However, they all should follow the same format.

  1. Declaration on the first line
  2. Body on subsequent line(s)
  3. Closing curly brace on the final line by itself (or with a semicolon when necessary)
// Named functions
function funcName() {
  return 'asdf';
}

// Anonymous functions assigned to variable
var otherFunc = function() {
  return 'asdf';
};

// Anonymous functions as parameters
var func = function(callback) {
  return callback() + ' Hello!';
};

func(function() {
  return 'I said,';
});

// Self invoking anonymous functions
var selfInvoking = (function() {
  return 'asdf';
})();

Always put the opening curly brace on the same line as the function declaration.

// bad
function ewww()
{
  return 'Ewww....';
}


// good
function yes() {
  return 'Awesome!';
}

Properties

Prefer multi-line object creation.

// Not great
var foo = { bar: 'fiz' };

// Good
var foo = {
  bar: 'fiz'
};

Prefer dot notation over string key access.

// No great
var bar = foo['bar'];

// good
var bar = foo.bar;

Unless you want to access an object with a variable key.

var key = 'bar';
var bar = foo[key];

Hoisting

Hoist variables BEFORE you assign them.

// bad
if (getSomeValue()) {
  something = 'asdf';
} else {
  something = 'fdsa';
}
var something;

// good
var anotherThing;

if (getSomeValue()) {
  anotherThing = 'asdf';
} else {
  anotherThing = 'fdsa';
}

Prefer comma separated variable names when hoisting multiple variables.

// bad
var one;
var two;
var three;

// good
var one,
    two,
    three;

Comparison

Prefer === and !== over == and !=. This will eliminate edge cases like these.

// bad
0 == false
// => true


// good
0 === false
// => false


// bad
1 == true
// => true

// good
1 === true
// => false

Comments

Single line comments use two slashes //.

// My single line comment

Multi-line comments use /* */.

/*
 * myFunction
 *
 * @param num Number
 * @return Number
 */

Using eval()

Don't use eval(). There's usually a better way to handle it.

Using this

Prefer using this in constructors and object methods. Avoid using it in the global namespace where its value is ambiguous.

// bad
this.foo = 'bar';
this.bar = function() {
  return this.foo;
};

// good
var Foo = function() {
  this.bar = 'fiz';
};

Looping with for-in

Use for-in loops only when looping through an object's keys. Not when looping through an array.

// bad
var array = [1, 2, 3, 4];

for (var index in array) {
  console.log(array[index]);
}


// good
var object = {
  one: 'one',
  two: 'two',
  three: 'three'
};

for (var key in object) {
  console.log(object[key]);
}

Associative Arrays and Objects

Prefer objects when keys are needed. Arrays inherit from Object and support keys, however, a distinction should be made.

When integer indexes are needed, use arrays; when hash map keys are needed, use objects.

// bad
var object = {};
object[0] = 'fiz';

// good
var array = [];
array[0] = 'fiz';

// bad
var array = [];
array['foo'] = 'bar';

// good
var object = {};
var object.foo = 'bar';

Formatting

Use 2 spaces per indent

// bad
if (foo) {
    alert('Nope');
}

// good
if (foo) {
  alert('Yup');
}

Put a space between if for while and similar conditional/looping constructs and their opening parenthesis. Likewise, follow the closing parenthesis with a space before the opening curly brace.

// bad
if(foo){
  alert('No');
}

// good
if (foo) {
  alert('Yes');
}


// bad
var i = 0;
while(i<10){
  i++;
}

// good
var i = 0;
while (i < 10) {
  i++;
}

// bad
for(var i=0;i<100;i++){
  console.log(i);
}

// good
for (var i = 0; i < 100; i++) {
  console.log(i);
}

// bad
switch(key){
  case'foo':
    break;
  case'bar':
    break;
  default:
    console.log('Something important');
}

// good
switch (key) {
  case 'foo':
    break;
  case 'bar':
    break;
  default:
    console.log('Something important');
}

Use 1 space between operators (logical and arithmetic).

// bad
var i = 1+1;

var j = array[i-1];

if (foo&&bar&&baz) {
  alert('No');
}

// good
var i = 1 + 1;

var j = array[i - 1];

if (foo && bar && baz) {
  alert('Yes');
}

Prefer non aligned initialization lists.

// bad
MyObject.prototype = {
  a                             : 0,
  b                             : 1,
  someReallyStupidLongIdentifier: 3
};

// good
MyObject.prototype = {
  a: 0,
  b: 1,
  someReallyStupidLongIdentifier: 3
};

If you're looking for a one size fits all solution in regards to formatting, check out prettier, which has quickly risen to become the standard in formatting across a plethora of grand open-source projects.

Type Coercions

There are many ways to convert a number to a string and vice versa. Just keep in mind that some are more clear than others.

// Not so clear
var str = '1234';
var num = +str;

str = num + '';

num = ~~str;


// Clear
var str = '1234';
var num = parseInt(str);

var str = num.toString();
str = String(num);

Prefer the double bang for coercion to boolean.

// Works but not great
var object = {};
var myBoolean = Boolean(object);

// Better
var object = {};
var myBoolean = !!object;

Method Chaining

Separate method calls onto new lines.

// bad
object.foo().bar().baz().fiz();

// good
object.foo()
  .bar()
  .baz()
  .fiz();

Constructors

Always provide an argument list with constructors even if it is empty.

// bad
var object = new MyObject;


// good
var object = new MyObject();

Want More Style?

These guidelines will keep your code clean, consistent, and readable. If you want a few more sources for JavaScript coding style you should check out the following links to the style guides for some majors companies.

Text Editor Setup

As a final note, it can be very helpful to set up your text editor with a few extra bells and whistles like a linter or formatter. As an example, see how Elad Ossadon set up is Atom for JS editing. You don't have to do exactly the same but should consider helping yourself out where you can with some additional packages.



Sign up to track your progress for free

There are ( ) additional resources for this lesson. Check them out!

There are no additional resources for this lesson just yet!

Sorry, comments aren't active just yet!

Next Lesson: Test Yourself: ES6 Tips and Best Practices