Skip to content

Common ES6+ Mistakes

This lesson explains Common ES6+ Mistakes with clear examples, use cases, and best practices so you can use modern JavaScript confidently in real projects.

Common ES6 Mistakes

ES6 introduced many powerful features that make JavaScript cleaner, safer, and easier to maintain. However, developers often misuse these features, leading to bugs, performance issues, memory leaks, and unexpected behavior. This guide covers the most common ES6 mistakes grouped by category along with the correct approach.

1. Variables (let, const, var)

  • Using var instead of let or const.
  • Using let when the value never changes.
  • Redeclaring variables in the same scope.
  • Accessing variables before declaration (Temporal Dead Zone).
  • Expecting var to be block scoped.
  • Creating accidental global variables.
  • Reassigning constants.
  • Declaring variables too early instead of near usage.
// Wrong

var total = 10;

// Better

const total = 10;

2. Block Scope

  • Trying to access let outside its block.
  • Using loop variables after the loop.
  • Assuming nested blocks share variables.
  • Using var inside loops.
  • Ignoring block scope inside switch statements.

3. Arrow Functions

  • Using arrow functions as object methods.
  • Expecting arrow functions to have their own this.
  • Using arrow functions as constructors.
  • Forgetting implicit return rules.
  • Returning object literals without parentheses.
  • Using arrows everywhere even when regular functions are clearer.
  • Using arrows for DOM event handlers without understanding lexical this.
  • Using arrows in prototypes unnecessarily.
// Wrong

const user =
  {
    name: "John",

    greet: () => {
      console.log(this.name);
    }
  };

4. Template Literals

  • Using string concatenation instead of interpolation.
  • Mixing quotes and backticks.
  • Creating unreadable multi-line templates.
  • Embedding complex logic inside template strings.
  • Not escaping backticks when needed.

5. Destructuring

  • Destructuring undefined objects.
  • Using incorrect property names.
  • Ignoring default values.
  • Overusing nested destructuring.
  • Confusing array and object destructuring.
  • Mutating destructured values expecting originals to update.
// May fail

const { name } =
  undefined;

6. Spread Operator

  • Thinking spread performs deep copies.
  • Using spread on non-iterables.
  • Overusing spread inside loops.
  • Accidentally overwriting object properties.
  • Copying huge arrays repeatedly.

7. Rest Parameters

  • Using rest anywhere except the last parameter.
  • Confusing rest with spread.
  • Using arguments in arrow functions.
  • Passing arrays instead of individual values.

8. Default Parameters

  • Passing null expecting the default value.
  • Using mutable default objects.
  • Using expensive function calls as defaults.
  • Ignoring parameter order.

9. Classes

  • Forgetting new.
  • Using classes for simple objects.
  • Deep inheritance chains.
  • Not calling super().
  • Confusing static and instance methods.
  • Accessing private fields directly.
  • Forgetting method binding.
  • Putting unrelated logic inside one class.

10. Modules

  • Mixing CommonJS with ES Modules.
  • Incorrect default import syntax.
  • Circular dependencies.
  • Using relative paths incorrectly.
  • Exporting too many unrelated items.
  • Importing entire libraries unnecessarily.

11. Promises

  • Forgetting to return promises.
  • Ignoring rejected promises.
  • Nesting multiple then blocks.
  • Mixing callbacks and promises.
  • Creating unnecessary promises.
  • Ignoring finally.
  • Promise constructor anti-pattern.
  • Unhandled promise rejections.

12. Async Await

  • Forgetting await.
  • Using await inside non-async functions.
  • Awaiting independent operations sequentially.
  • Ignoring try/catch.
  • Blocking loops with await.
  • Using await unnecessarily.
  • Not using Promise.all() for parallel requests.
  • Ignoring timeout handling.

13. Arrays

  • Using map without returning values.
  • Using map instead of forEach.
  • Using filter instead of find.
  • Mutating arrays accidentally.
  • Ignoring immutable updates.
  • Using reduce for simple loops.
  • Forgetting includes exists.
  • Using sort without comparator.

14. Objects

  • Mutating shared objects.
  • Using == instead of ===.
  • Copying nested objects incorrectly.
  • Forgetting Object.freeze for constants.
  • Using objects where Map is better.
  • Confusing property references.

15. Map and Set

  • Using objects instead of Map.
  • Using arrays instead of Set.
  • Expecting Set to sort values.
  • Using object keys incorrectly.
  • Ignoring Map iteration methods.

16. BigInt

  • Mixing Number and BigInt.
  • Expecting decimal support.
  • Using Math functions with BigInt.
  • JSON serialization errors.
  • Using BigInt unnecessarily.

17. Optional Chaining

  • Using optional chaining everywhere.
  • Ignoring actual programming errors.
  • Using it on required properties.
  • Confusing null with undefined.

18. Nullish Coalescing

  • Confusing ?? with ||.
  • Replacing valid zero values.
  • Ignoring null and undefined differences.
  • Combining operators incorrectly.

19. Iteration

  • Using for...in on arrays.
  • Using forEach with async.
  • Using await inside forEach.
  • Ignoring iterator protocols.
  • Creating unnecessary loops.

20. Browser Compatibility

  • Ignoring browser support.
  • Skipping Babel.
  • Missing polyfills.
  • Ignoring older mobile browsers.
  • Testing only in Chrome.

21. Performance Mistakes

  • Creating unnecessary object copies.
  • Using spread inside large loops.
  • Creating functions inside render loops.
  • Ignoring lazy loading.
  • Deep cloning large objects repeatedly.
  • Using async where synchronous code is sufficient.
  • Overusing classes.
  • Creating unnecessary promises.

22. Interview Mistakes

  • Saying classes replace prototypes.
  • Confusing spread and rest.
  • Confusing == and ===.
  • Not knowing lexical this.
  • Not understanding closures.
  • Ignoring Promise lifecycle.
  • Not understanding async execution.
  • Memorizing syntax without understanding behavior.

23. Production Code Mistakes

  • Missing error handling.
  • Not validating API responses.
  • Mutating application state.
  • Using global variables.
  • Ignoring linting rules.
  • Ignoring accessibility.
  • Skipping unit tests.
  • Skipping code reviews.

24. Security Mistakes

  • Using eval().
  • Trusting user input.
  • Ignoring XSS protection.
  • Using innerHTML carelessly.
  • Hardcoding secrets.
  • Ignoring CSP policies.
  • Exposing API keys.
  • Ignoring HTTPS.

25. ES6 Mistake Prevention Checklist

  • Prefer const whenever possible.
  • Use let only for mutable values.
  • Avoid var.
  • Use arrow functions appropriately.
  • Use destructuring carefully.
  • Handle Promise errors.
  • Use async/await with try/catch.
  • Prefer immutable updates.
  • Use modules.
  • Write small reusable functions.
  • Keep classes focused.
  • Test across browsers.
  • Use ESLint and Prettier.
  • Write unit tests.
  • Review performance regularly.

Interview Tip

Senior JavaScript interviews rarely focus on ES6 syntax alone. They often ask about the mistakes developers make with ES6 features and how to avoid them. Understanding these pitfalls demonstrates practical, production-level JavaScript experience.