JavaScript: the Bad Parts

By Xah Lee. Date: . Last updated: .

This page is a list of do and don'ts for JavaScript. Ordered roughly from most important to less.

Always Declare All Variables

Always declare all variables, and declare them inside functions.

First, you should never use variable at top level of source code, as they are global variables, and becomes a property of the window object. It contaminates the whole environment.

So, that leaves you inside functions. Then, you must declare, because otherwise it is global variable.

Never Use 「with」 Statement

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

Using with clouds the semantics of your program. Because the object of the with can have properties that collide with local variables, it can drastically change the meaning of your program. For example, what does this do?

with (foo) {
  var x = 3;
  return x;
}

Answer: anything. The local variable x could be clobbered by a property of foo and perhaps it even has a setter, in which case assigning 3 could cause lots of other code to execute. Don't use with.

from http://google.github.io/styleguide/javascriptguide.xml

Never Use ==

• Never Use ==. The == does automatic type conversion.

// Can you tell what following prints?

console.log(
    [] == ""
);

console.log(
    "" == {}
);

console.log(
    "0" == 0
);

console.log(
    "" == 0
);

console.log(
    1 == true
);

Use === instead.

Always Use Semicolon

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

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

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

// compiler error

〔➤see JavaScript: Semicolon

Never Use the Property “constructor”

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

Every function f has a property key "prototype" (f.prototype). 〔➤see JavaScript: Property Key "prototype"ES2015 §ECMAScript Language: Functions and Classes#sec-function-definitions-runtime-semantics-evaluation

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 JavaScript: 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. 〔➤see JavaScript “instanceof” Operator

Typically, a user expect to find the “class” that created the object, as the name “instance of” implies. But, JavaScript does not have “classes”, as JavaScript is not OOP in the Java, C++, Python, Ruby, sense. JavaScript is a prototype based language. Object has other object as parent. There's no class.

What instanceof is doing is trying to emulate checking “classs” by trying to find a object's creator function, relying on checking the prototype property f.prototype, and trying to see that value is in the prototype chain of the object.

Lots of things can go wrong, because:

To find a object's subtype, use Object.prototype.toString.call(x). 〔➤see JavaScript: Determine Type of Object

To determine if a object is in the prototype chain of another, use isPrototypeOf. See: JavaScript: Find Object's Prototype/Parent.

Never use the Constructor Array

Never use the constructor function Array, because its behavior is very complex, and you risk creating JavaScript's particular idea of sparse array that is very complex and unnatural, especially because JavaScript array is already complex because it is key/value pairs in disguise with a magical length property.

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

Never use the Constructor Object

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

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


Things to Avoid

Avoid 「for (‹x› in ‹obj›) {…}」 for Looping Thru Properties

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 JavaScript: Access/List Properties

Avoid use the Constructor Function

Avoid using the constructor function Function.

The only use of Function is for it to generate function at run-time. For normal function definition, just use function … {…}. 〔➤see JavaScript: Function Constructor

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 JavaScript: Keyword “this”

You can use Object.create().

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

〔➤see JavaScript: 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 JavaScript: 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 JavaScript: 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.

Like what you read? Buy JavaScript in Depth
or, buy a new keyboard, see Keyboard Reviews.