1. Missing curly braces
for. Although it is allowed, you should be extra careful, because this practice can often conceal problems and be the source of bugs. See the below example:
fail()call is indented and looks as if it belongs to the
ifstatement, it does not. It is always called. So it is a good practice to always surround blocks of code with curly braces, even if there is only one statement involved.
2. Missing semicolons
Because there is a semicolon missing on line 3, the parser assumes that the opening bracket on line 5 is an attempt to access a property using the array accessor syntax (see mistake #8), and not a separate array, which is not what was intended and results in a type error. The fix is simple – always write semicolons.
3. Not understanding type coercion
The problem can be easily fixed by using
parseInt(textBox.value, 10)to turn the string into a number before adding 10 to it. Depending on how you use a variable, the runtime might decide that it should be converted in one type or another. This is known as type coercion. To prevent types from being implicitly converted when comparing variables in
ifstatements, you can usestrict equality checks (===).
4. Forgetting var
Another practice that beginners are guilty of, is forgetting to use the
varstatement, it will silently declare it for you globally. This can be the source of subtle bugs. Here is an example, which also shows a different bug – missing a comma when declaring multiple variables at once:
When the parser reaches line 4, it will insert a semicolon automatically, and then interpret the
5. Arithmetic operations with floats
To work around this problem, you should not use use decimals if you need absolute correctness – use whole numbers, or if you need to work with money, use a library likebignumber.js.
6. Using constructors over literals
new String(). Although they are perfectly supported, it is recommended to use the literal notations:
"", because the constructor functions have subtle peculiarities:
The solution is simple: try to always use the literal notation. Besides, JS arrays don’t need to know their length in advance.
7. Not understanding how scopes work
Functions retain visibility to variables in their parent scopes. But because we are delaying the execution with a
setTimeout, when the time comes for the functions to actually run, the loop has already finished and the
ivariable is incremented to 11.
The self executing function in the comment works, because it copies the
ivariable by value and keeps a private copy for each timeout function. Read more about scopes here and here.
8. Using eval
Eval is evil. It is considered a bad practice, and most of the times when you use it, there is a better and faster approach.
9. Not understanding asynchronous code
Even though the
console.logcomes after the
load()function call, it is actually executed before the data is fetched.
10. Misusing event listeners
Let’s say that you want to listen for clicks on a button, but only while a checkbox is checked. Here is how a beginner might do it (using jQuery):
This is obviously wrong. Ideally, you should listen for an event only once, like we did with the checkbox’s change event. Repeatedly calling
button.on('clicked' ..)results in multiple event listeners that are never removed. I will leave it as an exercise for the reader to make this example work :)
The best way to prevent mistakes like these from happening is to use JSHint. Some IDEs offer built-in integration with the tool, so your code is checked while you write. I hope that you found this list interesting. If you have any suggestions, bring them to the comment section!