DEV Community

Cover image for Common JavaScript Mistakes and How to Fix Them
John Liter
John Liter

Posted on

Common JavaScript Mistakes and How to Fix Them

Common JavaScript Mistakes and How to Fix Them

JavaScript is a powerful yet quirky language, and even experienced developers make mistakes. Whether you're a beginner or a seasoned coder, avoiding these common pitfalls will save you hours of debugging.

In this article, I’ll cover 10 frequent JavaScript mistakes and how to fix them—with practical examples and best practices. Let’s dive in!

Table of Contents

1. Using == Instead of ===

The Mistake\
Using loose equality (==) can lead to unexpected type coercion:

console.log(5 == "5"); // true (WAT?!)
Enter fullscreen mode Exit fullscreen mode

The Fix\
Always use strict equality (===) to compare both value and type:

console.log(5 === "5"); // false (correct)
Enter fullscreen mode Exit fullscreen mode

2. Not Handling undefined or null

The Mistake\
Assuming a variable exists without checks:

function greet(user) {  
  return "Hello, " + user.name; // 💥 if user is undefined  
}
Enter fullscreen mode Exit fullscreen mode

The Fix\
Use optional chaining (?.) or default values:

function greet(user) {  
  return "Hello, " + (user?.name ?? "Guest");  
}
Enter fullscreen mode Exit fullscreen mode

3. Modifying Objects While Iterating

The Mistake\
Modifying an array while looping can cause bugs:

const users = ["Alice", "Bob", "Charlie"];  
users.forEach(user => {  
  if (user === "Bob") users.shift(); // Mutates array mid-loop  
});
Enter fullscreen mode Exit fullscreen mode

The Fix\
Create a copy of the array first:

[...users].forEach(user => {
  /* safe iteration */
});
Enter fullscreen mode Exit fullscreen mode

4. Ignoring Asynchronous Behavior

The Mistake\
Assuming async code runs sequentially:

let data;  
fetch("/api/data").then(res => data = res);  
console.log(data); // undefined 😱
Enter fullscreen mode Exit fullscreen mode

The Fix\
Use async/await for cleaner async handling:

async function loadData() {  
  const data = await fetch("/api/data");  
  console.log(data); // Works!  
}
Enter fullscreen mode Exit fullscreen mode

5. Memory Leaks with Event Listeners

The Mistake\
Forgetting to remove event listeners:

button.addEventListener("click", onClick);  
// Later...
button.remove(); // Listener still in memory!
Enter fullscreen mode Exit fullscreen mode

The Fix\
Always clean up listeners:

button.addEventListener("click", onClick);  
// On removal:
button.removeEventListener("click", onClick);
Enter fullscreen mode Exit fullscreen mode

6. Misusing this in Callbacks

The Mistake\
Losing this context in callbacks:

class User {  
  constructor(name) { this.name = name; }  
  greet() {
    setTimeout(function() {  
      console.log("Hello, " + this.name); // 😵 `this` is `window`!
    }, 1000);
  }  
}
Enter fullscreen mode Exit fullscreen mode

The Fix\
Use arrow functions (they don’t rebind this):

setTimeout(() => console.log("Hello, " + this.name), 1000);
Enter fullscreen mode Exit fullscreen mode

7. Blocking the Event Loop

The Mistake\
Running CPU-heavy tasks synchronously:

function processLargeData() {  
  // Blocks UI for seconds ⏳
  for (let i = 0; i < 1e9; i++);
}
Enter fullscreen mode Exit fullscreen mode

The Fix\
Use Web Workers or chunk tasks:

setTimeout(() => processChunk(), 0); // Yields to the event loop
Enter fullscreen mode Exit fullscreen mode

8. Not Catching Promise Rejections

The Mistake\
Unhandled promise rejections crash Node.js apps:

fetch("/api").then(res => res.json()); // No .catch()!
Enter fullscreen mode Exit fullscreen mode

The Fix\
Always handle errors:

fetch("/api")  
  .then(res => res.json())  
  .catch(err => console.error("API failed:", err));
Enter fullscreen mode Exit fullscreen mode

9. Mutating State Directly (React/Angular/Vue)

The Mistake\
Changing state directly in frameworks:

const [users, setUsers] = useState([]);  
users.push("Alice"); // 🚫 Doesn’t trigger re-render
Enter fullscreen mode Exit fullscreen mode

The Fix\
Always use immutable updates:

setUsers([...users, "Alice"]); // ✅ Correct
Enter fullscreen mode Exit fullscreen mode

10. Overusing var Instead of let/const

The Mistake\
var has function scope, leading to bugs:

for (var i = 0; i < 3; i++) {  
  setTimeout(() => console.log(i), 100); // Logs 3, 3, 3 😬
}
Enter fullscreen mode Exit fullscreen mode

The Fix\
Use let (block-scoped):

for (let i = 0; i < 3; i++) {  
  setTimeout(() => console.log(i), 100); // Logs 0, 1, 2 ✅
}
Enter fullscreen mode Exit fullscreen mode

Final Tips to Avoid JS Mistakes

✔ Use TypeScript for static type checking.\
✔ Enable ESLint to catch errors early.\
✔ Write tests (Jest, Mocha) to prevent regressions.\
✔ Read MDN Docs when unsure about a method.

Top comments (0)