8 Common JavaScript Pitfalls Every Developer Should Avoid

This article outlines eight frequent JavaScript traps—from type coercion and variable hoisting to this binding, closures, numeric precision, array method quirks, Promise misuse, and event‑listener memory leaks—explaining why they occur and how to resolve them.

JavaScript
JavaScript
JavaScript
8 Common JavaScript Pitfalls Every Developer Should Avoid

JavaScript is a flexible language with many confusing features that can trap even experienced developers. This article shares common pitfalls and their solutions.

1. Type coercion confusion

JavaScript's type conversion rules can produce unexpected results. When using the + operator, operands are first converted to primitive types.

console.log([] + []); // ""
console.log([] + {}); // "[object Object]"
console.log({} + []); // 0 (in some browsers)
console.log([] == ![]); // true

These results follow the language's conversion algorithm.

2. Variable hoisting trap

console.log(a); // undefined
var a = 1;

console.log(b); // ReferenceError
let b = 2;

Variables declared with var are hoisted to the top of their scope but their initialization is not. let and const have a temporal dead zone and throw an error when accessed before declaration.

3. this binding issue

const obj = {
    name: 'XiaoMing',
    sayHi() {
        setTimeout(function() {
            console.log('Hello, ' + this.name);
        }, 100);
    }
};
obj.sayHi(); // Hello, undefined

In the callback, this refers to the global object (or undefined in strict mode) instead of obj. Solutions include using an arrow function or bind:

// Arrow function
setTimeout(() => {
    console.log('Hello, ' + this.name);
}, 100);

// bind
setTimeout(function() {
    console.log('Hello, ' + this.name);
}.bind(this), 100);

4. Closure trap

for (var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i);
    }, 100);
}
// Output: 3, 3, 3

Because var is function‑scoped, all callbacks share the same i. Using let or an IIFE fixes the issue.

5. Numeric precision problem

console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false

JavaScript uses IEEE‑754 double‑precision floating‑point numbers, so some decimals cannot be represented exactly. Use rounding or libraries for precise arithmetic.

6. Array method pitfalls

Solutions are illustrated in the accompanying diagram.

7. Common Promise pitfalls

Correct usage patterns are shown in the following diagram.

8. Event listener memory leak

// Bad example (possible leak)
function addHandler() {
    const element = document.getElementById('button');
    element.addEventListener('click', () => {
        console.log('Clicked');
    });
}

// Good example
function addHandler() {
    const element = document.getElementById('button');
    const handler = () => {
        console.log('Clicked');
    };
    element.addEventListener('click', handler);
    // Cleanup
    return () => {
        element.removeEventListener('click', handler);
    };
}

Properly removing listeners prevents memory leaks.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendJavaScriptbugspromisesclosuresthis binding
JavaScript
Written by

JavaScript

Provides JavaScript enthusiasts with tutorials and experience sharing on web front‑end technologies, including JavaScript, Node.js, Deno, Vue.js, React, Angular, HTML5, CSS3, and more.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.