Welcome to QAFlow! Ask questions and get answers from our community.
Programming

7 Common JavaScript Mistakes That Even Senior Developers Make

admin
Apr 13, 2026 · 3.1K views · 1 min read

JavaScript is full of quirks and edge cases. Even experienced developers fall into these traps. Let's look at 7 common mistakes and how to avoid them.

1. Not Handling Promise Rejections

// BAD - Unhandled rejection
async function fetchUser(id) {
    const response = await fetch(`/api/users/${id}`);
    return response.json(); // What if fetch fails?
}

// GOOD - Always handle errors
async function fetchUser(id) {
    try {
        const response = await fetch(`/api/users/${id}`);
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        return response.json();
    } catch (error) {
        console.error("Failed to fetch user:", error);
        return null;
    }
}

2. Comparing with == Instead of ===

// Surprising results with ==
0 == ""          // true
0 == "0"         // true
"" == "0"        // false (wait, what?)
false == "false" // false
false == "0"     // true
null == undefined // true

// Always use === for predictable behavior
0 === ""  // false
0 === "0" // false

3. Mutating Objects Passed as Arguments

// BAD - Mutates the original
function addDiscount(product) {
    product.price *= 0.9; // This changes the original object!
    return product;
}

// GOOD - Create a new object
function addDiscount(product) {
    return { ...product, price: product.price * 0.9 };
}

4. forEach with Async/Await

// BAD - forEach doesn't await
async function processItems(items) {
    items.forEach(async (item) => {
        await saveToDatabase(item); // These run in parallel, not sequentially!
    });
    console.log("Done!"); // This runs BEFORE saves complete
}

// GOOD - Use for...of for sequential
async function processItems(items) {
    for (const item of items) {
        await saveToDatabase(item);
    }
    console.log("Done!"); // Now this is correct
}

// GOOD - Use Promise.all for parallel
async function processItems(items) {
    await Promise.all(items.map(item => saveToDatabase(item)));
    console.log("Done!");
}

5. Memory Leaks with Event Listeners

// BAD - Never cleaned up
function setupComponent() {
    window.addEventListener("resize", handleResize);
    document.addEventListener("click", handleClick);
}

// GOOD - Clean up when done
function setupComponent() {
    const controller = new AbortController();
    window.addEventListener("resize", handleResize, { signal: controller.signal });
    document.addEventListener("click", handleClick, { signal: controller.signal });

    // Clean up all listeners at once
    return () => controller.abort();
}

6. Floating Point Arithmetic

// The classic gotcha
0.1 + 0.2 === 0.3  // false! (it's 0.30000000000000004)

// Solution: Use epsilon comparison or integers
Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON  // true

// Or work with cents (integers)
const priceInCents = 1099; // $10.99

7. Ignoring Optional Chaining and Nullish Coalescing

// OLD - Verbose null checks
const city = user && user.address && user.address.city
    ? user.address.city
    : "Unknown";

// MODERN - Clean and readable
const city = user?.address?.city ?? "Unknown";

// Works with methods too
const result = api?.getData?.() ?? defaultValue;

Key Takeaways

  • Always use === for comparisons
  • Handle async errors explicitly
  • Never mutate function arguments
  • Clean up event listeners and subscriptions
  • Use modern syntax features for safety
admin
295 rep 22 posts

No bio yet.

Comments (0)
Login to leave a comment.

No comments yet. Be the first!

About Author
admin
295 rep 22 posts

No bio available.

View Profile
Subscribe to Newsletter

Get the latest posts delivered to your inbox