JavaScript Style Guide

By Xah Lee. Date: . Last updated: .

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

Never use var

Never use var. It is from early days of JavaScript. It has complex variable scope [see var Name Scope] , and complex name-hoisting behavior. [see var Declaration Order]

Always use let or const instead.

Always Declare Variable

Never have undeclared variable such as: x = 3. Always declare them by let or const .

Never Use ==

Never use double equal ==. The == does type conversion implicitly, which returns true for [] == "", etc. Use triple equal === instead. [see Equality]

Never Use “with” Statement

The with statement creates semantic ambiguity of code inside its curly brackets, if local variable are declared using var, it can mean the property of a object.

For example,

const jj = {x:4};

with (jj) {
    var x = 3; // x is meant to be local variable
}

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

This is tricky, because the variable x can mean multiple things.

If y has a property x, then x means y.x, else it means the local variable x.

You have to watch out whenever you use a local variable. But you may not know what property y has.

The problem goes away if you use let to declare local variable.

const jj = {x:4};

with (jj) {
    let x = 3;
}

console.log( jj );
// { x: 4 }
// jj.x is not changed

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 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 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).

Lots of things can go wrong, because:

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

[see Determine Type of Object]

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

Never Use Object Constructor “Object()”

Never use the Object Constructor Object() to create a object, because its behavior is complex. Use it only to convert a primitive value to object type.

To create object, use Object Literal Expression {}, or use Object.create .

Avoid for-in Loop

When you use for-in Loop , for (x in obj) {}, it goes thru the prototype-chain. That's almost never what you want.

To go thru properties, use: Object.keys or Object.getOwnPropertyNames then use Array.prototype.forEach [see List Properties]

Avoid Using “eval()”

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

Avoid Using Keyword “this”

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

Use Object.create

See also: Use Object.create to Emulate Constructor

Douglas Crockford, said he stopped using this and new. [see 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. Douglas Crockford the Better Parts: the Bads Parts Reconsidered .

[see 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 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 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: Why I Hate Exceptions .

Never Use Accessor Properties

Getter/Setter Properties are complex, and are not necessary. They are methods pretending to be properties. Just define methods explicitly if you need to. This way, it is explict what the code is doing.

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 Semicolon]

Never Use the Delete Operator

You should NEVER use the Delete operator .

Never use Function.prototype.Call, Function.prototype.Apply

See Function Call, Apply, Bind.

Use Reflect.apply instead, because it avoids JavaScript complex prototype chain, and makes the code clearer.

Avoid Keyword “function” to Define a Function

See Define Function. Always use Arrow Function.

Functions defined by keyword function has the complex this Binding and complex “arguments” Object. Also the complex hoisting behavior and scope issues. See Function Declaration vs Function Expression .

Arrow function simply do not have thisBinding or argument object, nor hoisting behavior nor nesting scope problems.

JS in Depth
XAH  BUY NOW

JS in Depth

JS Obj Ref

DOM


JS in Depth

Basic Syntax

Value Types

Variable

String

Function

Property

Object and Inheritance

Array

Constructor/Class

Iterable 🌟

Misc