There are plenty of posts discussing anti-patterns in other languages, like Java or Python. However, I haven’t really seen much regarding JavaScript besides this question on StackOverflow. And most of the ones I found don’t separate the DOM API and the JavaScript language itself.
So the following is a list of JavaScript anti-patterns that I’ve compiled, with some explanations.
Polluting the global namespace
This is the biggest no-no, and is something all new JavaScript developers must learn. The reason you don’t want to declare too many variables in the global namespace is the avoid conflicts with code written by others or yourself. Here’s an example to illustrate this:
In this example, i=5
at the end of execution. This happens because the variable i
both inside and outside the function left out the var
declaration, thus the engine declares it in the global namespace. And if everyone’s code rely on global variables, you may break someone else’s code accidentally.
Extending the Object prototype
Never, never, never extend Object.prototype. By doing that you could break a lot of code that do things such as for (var a in myObj)
– such as jQuery. That is the very reason why Crockford’s jslint promotes the use of hasOwnProperty()
check. But IMO that produces ugly code. The better way is to just leave Object.prototype
alone.
Using multiple var declarations instead of one
In each scope you can make multiple variable declarations by separating each one with a comma. This makes code more readable, and performs better too (albeit by a very small margin).
Using new Array() and new Object()
Please don’t declare arrays and hashes like this.
When you do this instead.
Not making use of truthy/falsey values: undefined, null, false, ”, [], etc.
In JavaScript, a variable’s value can be truthy or falsey. This mean that while the value isn’t strictly equivalent to the boolean values true and false, they can be coerced into a boolean value.
You can run quick tests in your browser to check if something is truthy or falsey.
Not making use of truthy/falsey values (part 2): for loops
Another great use of truthy and falsey is in a for loop. In most other languages, the exit-check of the loop usually makes sure the index does not go out of bounds. But in JavaScript we can do one better!
The second for loop works because arr[i]
is undefined if i
is an out-of-bounds index, and undefined
is falsey. Also, this method performs better (especially in IE 6/7 where arr.length
lookup can be costly). Be careful not to use this approach if you know an array may contain a zero (0), or any other falsey values you don’t want to prematurely exit from.
Using switch statements
Update: 2012-02-11
Switch statements have been optimized in modern JavaScript engines. Function hashes are still very useful when you need code reuse, or when to refactor a complex function into smaller, simpler ones.
A lot of times when you use a switch statement in JavaScript, you really should be using function hashes. This is because switch statements in JavaScript don’t perform as well as you’re probably used to in other languages.
Not making use of truthy/falsey values (part 3): Converting a value using Boolean(x)
Okay, I’m not sure if this counts a an anti-pattern but it’s more of a personal preference. Of course we should never use Boolean('')
inside an if-check, but sometimes we want to convert any value into an actual boolean. What you should do instead of using Boolean(x)
is to use !!x
. This works because !x returns true if x is falsey, and false otherwise. We then negate that boolean again to get what we want.
Using for-in loop over an array
Arrays in JavaScript are special objects, so a for-in loop doesn’t do what you think it does.
You may think you'll get the values of the array above, but you actually get the indices inside the array. It’s easier just to stick to normal for loops.