JavaScript Style Guide

By Xah Lee. Date: . Last updated: .

JavaScript Best practice. Ordered roughly from most important to less.

Always Declare Variable

All use of variable should be declared.

That is, never have

x = 3

where there's no any var, let, const before it. (unless it's been declared before and you are just changing the value.)

Never use 「var」

Try to alway use const. It can be used for object, function, array.

[see JS: const Declaration]

Use let if you have variable that need to be changed.

[see JS: let Declaration]

Never use var, unless you are working in pre ES2015 JavaScript.

var is from early days of JavaScript. It has very complex and bad semantics. That is, it has complex variable scope, and name-hoisting behavior (which is not simple to understand) See:

Never Use “with” Statement

The with statement creates semantic ambiguity of code inside its curly brackets.

For example,

const y = {x:4};

with (y) {
    var x = 3;
    // do something with x
}

console.log ( y );
// { x: 3 }
// y.x is changed

The x means y.x, if y has a property x.

This means, you have to watch out whenever you use a local variable. But you may not know what property y has. Also other people editing your code may not be aware it is inside a with statement. So its prone to create errors.

Never Use ==

Never use double equal ==.

// using == is unpredicable. Always use ===

console.log( [] == "" ); // true
console.log( "" == {} ); // false
console.log( "0" == 0 ); // true
console.log( "" == 0 ); // true
console.log( 1 == true );  // true

The == does type conversion implicitly.

Use triple equal === instead.

// using == is unpredicable. Always use ===

console.log( [] === "" ); // false
console.log( "" === {} ); // false
console.log( "0" === 0 ); // false
console.log( "" === 0 ); // false
console.log( 1 === true );  // false

Always Use Semicolon

Always use semicolon. Omitting semicolon creates hard-to-find bugs.

const f = function() {
    return 3;
} // bad semicolon omission

(function() {
    return 4;
})();

// TypeError: (intermediate value)(...) is not a function

[see JS: Semicolon]

Never Use the Property named “constructor”

Never use the property key "constructor". Because its value can be anything.

Every function f has a property key "prototype".

[see JS: Property Key "prototype"]

The value of it by default is {"constructor":f} (that is, a object with a property key "constructor", with value of the function itself).

[see JS: Property Key “constructor”]

Never use the “instanceof” Operator

Never use the instanceof operator. Because, what it actually does may not be what you expect, and there are better ways to do what you want.

obj instanceof f is basically the same as f.prototype.isPrototypeOf(obj).

[see JS: “instanceof” Operator]

Lots of things can go wrong, because:

To find a object's subtype, use Object.prototype.toString.call(x).

[see JS: Determine Type of Object]

To determine if a object is in the prototype chain of another, use isPrototypeOf.

[see JS: Get/Set Prototype]

Never use the Constructor named “Array”

Never use the constructor function Array, because its behavior is very complex, depending on the number of arguments and their type.

[see JS: Array Constructor]

Use array literal expression […] instead, then use “for loop” or array method “push” to fill or add elements.

[see JS: Array.prototype.push]

Never Use the Constructor Named “Object”

Never use the constructor function Object, because its behavior is complex.

[see JS: Object Constructor]

Use literal expression {…}, or use Object.create(…).

Avoid for-in Loop

When you use

for (x in obj) {…}

It goes thru the prototype-chain of obj. That's usually not what you want.

To go thru properties, use:

[see JS: List Properties]

Or use for-of loop for iterable object.

[see JS: for-of Loop]

Avoid use the Constructor named “Function”

Avoid using the constructor function Function.

[see JS: Function Constructor]

The only use of Function is for it to generate function at run-time. For normal function definition, just use function … {…}. Or better, always use arrow function.

[see JS: Arrow Function]

Avoid Using “eval()”

Using eval is sort of meta programing. But it has several problems.

Don't Change a Object's Parent

It's recommend you don't change a object's parent. Due to how JavaScript is implemented, changing a object's parent causes major slow down.

[see JS: Change an Object's Prototype]

Avoid Using Keyword “this”

Avoid using this keyword. Because, its value is dependent on calling context in a complex way. [see JS: “this” Binding]

You can use Object.create().

Douglas Crockford, said he stopped using this and new. [see JS: Douglas Crockford the Better Parts: the Bads Parts Reconsidered]

Avoid Using Operator 「new」

Avoid using new F, because its behavior is extremely complex, and drags in all the extremely other complex parts, the keyword this, the function prototype property, and constructor property.

Douglas Crockford stopped using new, perhaps you should consider it too. JS: Douglas Crockford the Better Parts: the Bads Parts Reconsidered.

[see JS: Operator “new”]

Instead, write a function that returns a object, and or use Object.create(). This way, you can more simply and reliably specify parent object or the prototype chain. [see JS: How to Use Object.create() to Emulate Constructor?]

Avoid Using Exceptions

As a programing style in general, you might consider avoid using the {Throw Try Catch Finally}. [see JS: Throw Try Catch Finally]

Because, they are implicit goto, and are prone to be abused. Meaning, it makes it hard to understand the program flow.

Write your program to handle error cases explicitly, locally.

For more detail, See: Programing: Why I Hate Exceptions.

Avoid Using Getter and Setter Methods

Getter and setter methods are complex, and are not necessary.

[see JS: Get/Set Prototype]

Liket it? Put $5 at patreon.

Or, Buy JavaScript in Depth

Patreon me $5. Ask me question on patreon