JavaScript Common Mistakes
Learn from common errors to write better JavaScript code
⚠️ Why Learn About Common Mistakes?
Understanding common JavaScript mistakes helps you avoid bugs, write cleaner code, and debug issues faster. Learning from these mistakes makes you a better developer!
// Common mistake: Forgetting to declare variables
function badExample() {
message = "Hello"; // Creates global variable accidentally!
}
// Correct way: Always declare variables
function goodExample() {
const message = "Hello"; // Properly scoped variable
}
Types of Common Mistakes
Variable Issues
Scope and declaration problems
Loop Problems
Common loop and iteration errors
Type Confusion
Data type and comparison issues
Async Errors
Asynchronous code mistakes
🔹 Variable Declaration Mistakes
One of the most common mistakes is improper variable declaration:
Common Variable Mistakes:
- Forgetting to declare variables (creates globals)
- Using var instead of let/const
- Redeclaring variables accidentally
- Not understanding hoisting behavior
// ❌ Mistake: Undeclared variable becomes global
function createUser() {
userName = "John"; // Oops! Global variable created
return userName;
}
// ✅ Fix: Properly declare variables
function createUser() {
const userName = "John"; // Properly scoped
return userName;
}
// ❌ Mistake: Using var in loops
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // Prints 3, 3, 3
}
// ✅ Fix: Using let in loops
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // Prints 0, 1, 2
}
Output:
First loop: 3, 3, 3 (wrong!)
Second loop: 0, 1, 2 (correct!)
🔹 Comparison Operator Mistakes
Using == instead of === can lead to unexpected results:
// ❌ Mistake: Using loose equality (==)
console.log(0 == false); // true (unexpected!)
console.log("" == false); // true (unexpected!)
console.log(null == undefined); // true (unexpected!)
console.log("5" == 5); // true (type coercion)
// ✅ Fix: Using strict equality (===)
console.log(0 === false); // false (correct)
console.log("" === false); // false (correct)
console.log(null === undefined); // false (correct)
console.log("5" === 5); // false (correct)
// ❌ Mistake: Not checking for NaN properly
const result = parseInt("abc");
if (result == NaN) { // This never works!
console.log("Not a number");
}
// ✅ Fix: Using Number.isNaN()
const result2 = parseInt("abc");
if (Number.isNaN(result2)) { // This works!
console.log("Not a number");
}
Output:
Loose equality can cause unexpected type conversions!
Always use === for reliable comparisons.
🔹 Array and Object Mistakes
Common mistakes when working with arrays and objects:
// ❌ Mistake: Modifying arrays while iterating
const numbers = [1, 2, 3, 4, 5];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] % 2 === 0) {
numbers.splice(i, 1); // Modifies array during iteration!
}
}
console.log(numbers); // [1, 3, 5] - but skipped some elements!
// ✅ Fix: Filter to create new array
const numbers2 = [1, 2, 3, 4, 5];
const oddNumbers = numbers2.filter(num => num % 2 !== 0);
console.log(oddNumbers); // [1, 3, 5] - correct!
// ❌ Mistake: Shallow copying objects
const original = { name: "John", hobbies: ["reading", "gaming"] };
const copy = original; // Not a copy, same reference!
copy.name = "Jane";
console.log(original.name); // "Jane" - original changed!
// ✅ Fix: Proper object copying
const original2 = { name: "John", hobbies: ["reading", "gaming"] };
const copy2 = { ...original2, hobbies: [...original2.hobbies] };
copy2.name = "Jane";
console.log(original2.name); // "John" - original unchanged!
🔹 Function and Scope Mistakes
Common errors with functions and variable scope:
// ❌ Mistake: Not understanding 'this' context
const user = {
name: "John",
greet: function() {
console.log("Hello, " + this.name);
}
};
const greetFunction = user.greet;
greetFunction(); // "Hello, undefined" - lost context!
// ✅ Fix: Bind the context or use arrow functions
const user2 = {
name: "John",
greet: function() {
console.log("Hello, " + this.name);
}
};
const boundGreet = user2.greet.bind(user2);
boundGreet(); // "Hello, John" - correct!
// ❌ Mistake: Creating functions in loops
const buttons = document.querySelectorAll('button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
console.log("Button " + i + " clicked"); // Always logs last i value!
};
}
// ✅ Fix: Use closure or let
const buttons2 = document.querySelectorAll('button');
for (let i = 0; i < buttons2.length; i++) {
buttons2[i].onclick = function() {
console.log("Button " + i + " clicked"); // Correct i value!
};
}
🔹 Async/Await Common Mistakes
Mistakes when working with asynchronous code:
Async Mistakes to Avoid:
- Forgetting await: Not waiting for promises to resolve
- Not handling errors: Missing try-catch blocks
- Sequential instead of parallel: Unnecessary waiting
- Mixing callbacks and promises: Inconsistent patterns
// ❌ Mistake: Forgetting await
async function fetchUserData() {
const response = fetch('/api/user'); // Missing await!
const data = response.json(); // This will fail!
return data;
}
// ✅ Fix: Proper await usage
async function fetchUserData() {
const response = await fetch('/api/user');
const data = await response.json();
return data;
}
// ❌ Mistake: Sequential when parallel is possible
async function loadAllData() {
const users = await fetchUsers(); // Wait for users
const posts = await fetchPosts(); // Then wait for posts
const comments = await fetchComments(); // Then wait for comments
return { users, posts, comments };
}
// ✅ Fix: Parallel execution
async function loadAllData() {
const [users, posts, comments] = await Promise.all([
fetchUsers(),
fetchPosts(),
fetchComments()
]);
return { users, posts, comments };
}