10 JavaScript Bad Practices You Should Avoid
JavaScript Best Practices That Will Totally Improve Your Code
JavaScript is a powerful language that allows developers to add interactivity and logic to web pages.
However, with great flexibility comes the temptation to fall into bad habits that can create bugs, performance issues, and maintenance headaches.
As an experienced JS developer, I want to share 10 common anti-patterns and bad practices that you should avoid in your code.
1. Using eval()
Theeval()
function allows you to execute arbitrary JavaScript code passed in as a string.
This is dangerous and should be avoided.
// Avoid
const userInput = getUserInput();
eval(userInput);
eval()
opens up your code to injection attacks and makes debugging difficult.
There are almost always better ways to evaluate code, like using a function constructor.
// Better
const userInput = getUserInput();
const func = new Function (userInput);
func();
2. Forgetting var/let/const
Declaring variables without a keyword like var
, let
or const
puts them in the global namespace, causing collisions.
// Avoid
function foo() {
bar = 'hello';
}
// Better
function foo() {
const bar = 'hello';
}
Get in the habit of properly declaring variables.
3. Dumping everything in the global namespace
Similarly, avoid defining many variables and functions in the global namespace.
This causes clashes with other scripts and libraries.
// Avoid
function foo() { ... }
const bar = 1;
// Better
const MyApp = {
foo: function() { ... },
bar: 1
};4
Use modules or encapsulated namespaces instead.
4. Missing semicolons
While JavaScript inserts semicolons automatically in most cases, it can lead to subtle errors in certain edge cases.
Explicit semicolons leave no room for confusion.
// Avoid
const sample = {}
const onemoresample = {}
[sample, onemoresample].forEach(notagain => notagain.parent = 'That's final')
// Better
const sample = {};
const onemoresample = {};
[sample, onemoresample].forEach(notagain => {
notagain.parent = 'That's final';
});
5. Using document.write()
document.write()
blocks page rendering and can overwrite the whole page.
Avoid it outside of very specific use cases.
// Avoid
document.write('Some new content');
// Better
const content = document.createElement('div');
content.innerHTML = 'Some new content';
document.body.appendChild(content);
6. Abusing typeof
and equality
Be careful when comparing types and equality in JavaScript.
// Avoid
if (x == '37') {
// this checks the value only
}
if (typeof x == 'object') {
// typeof null is 'object'
}
// Better
if (x === 37) {
// use === to check both value & type
}
if (x !== null && typeof x === 'object') {
// check null explicitly
}
7. Misusing this
The meaning of this
varies based on context.
Avoid ambiguity by binding this
or using arrow functions.
// Avoid
function logThis() {
console.log(this); // what's 'this'?
}
// Better
const logThis = () => {
console.log(this); // lexical 'this'
}
const obj = {
logThis: logThis.bind(this) // bound 'this'
};
8. Ignoring warnings
Don’t ignore linter and compiler warnings.
They often catch real issues.
9. Overoptimizing
Don’t sacrifice readability for minor performance gains without profiling.
// Unclear
const l=a.length; for(i=0;i<l;i++) { /*...*/ }
// Clearer
for (let i = 0; i < a.length; i++) {
/* ... */
}
Only optimize where needed based on benchmarks.
10. Not handling errors
Don’t fail silently — handle errors appropriately.
// Avoid
try {
dangerousOperation();
} catch (e) {}
// Better
try {
dangerousOperation();
} catch (e) {
console.error(e);
// handle error
}
Proper error handling avoids hidden bugs.
While JavaScript gives you flexibility, following best practices avoids nasty issues down the road.
Always keep these bad habits in mind to become a better, more efficient JS developer.
If this story provided value and you wish to show a little support, you could:
- Clap 50 times for this story (this really helps me out)
- Subscribe to get an email when I publish a new story