OOP in JavaScript
ES6 Classes — Syntax & Semantics
Master ES6 Classes in JavaScript. Learn class declarations, constructor execution, method definitions, and how classes map to prototypal inheritance under the hood.
1. Introduction
ES6 introduced the class keyword to write Object-Oriented Programming (OOP) syntax. While it resembles class definitions in languages like Java or C++, JavaScript classes are syntactic sugar over the language's existing prototype-based inheritance model.
2. Why It Matters
Using classes makes JavaScript code cleaner and easier to read. Additionally, classes enforce strict mode automatically and prevent calling constructors without the new keyword, reducing common runtime errors.
3. Real-World Analogy
Think of Writing Blueprints using Modern CAD Software:
- Legacy Prototypes (Hand-drawn sketches): Drawing separate layouts for the building foundations, then drawing separate instruction sheets for the plumbing, and linking them using paper clips. It works but is disorganized.
- ES6 Classes (Modern CAD blueprint): A unified CAD model workspace. You place the foundation configurations (constructor), the plumbing layout (methods), and security settings (strict mode guards) inside a single file container. The software compiles this into standard blueprints under the hood automatically.
4. Class Syntax & Semantics
A class is defined using the class keyword. The constructor method is called automatically when instantiating a new instance using the new keyword:
5. Classes under the Hood
Under the hood, class declarations create constructor functions:
• The class identifier UserAccount is a function reference.
• Methods defined inside the class body (like displayProfile()) are attached directly to UserAccount.prototype.
• Class declarations are not hoisted. Accessing a class before its declaration throws a ReferenceError.
6. Practical Example
This script demonstrates defining class methods as properties inside constructor functions vs defining them inside class signatures:
7. Common Mistakes
- • Calling a class constructor without the new keyword: Unlike legacy constructor functions which fail silently, calling a class constructor without the
newkeyword throws aTypeError: Class constructor UserAccount cannot be invoked without 'new'.
8. Quick Quiz
Q1: Where are class methods (like complete()) stored under the hood?
A) Stored on each object instance separately
B) Stored on the class's prototype object (Class.prototype)
Answer: B — Methods defined inside a class body are attached directly to the class's prototype object, sharing a single reference in memory across all instances.
9. Scenario-Based Challenge
The Legacy Prototype Refactor:
An older codebase implements user accounts using standard prototypes: function Member(name) { this.name = name } and Member.prototype.login = function() {}. Refactor this code block to use the modern ES6 class syntax.
10. Debugging Exercise
Explain why this instantiation crashes, and how to fix it:
const myLogger = new Logger('App'); // ReferenceError! Why?
class Logger { constructor(name) { this.name = name; } }
View Solution
Diagnosis: Unlike legacy constructor functions, class declarations are not hoisted. Attempting to instantiate a class before its declaration line throws a ReferenceError.
Fix: Declare the class before instantiating it:
class Logger { constructor(name) { this.name = name; } }
const myLogger = new Logger('App'); // Works!
11. Interview Questions
🟢 Q1: Explain why ES6 class syntax is described as "syntactic sugar".
Answer: ES6 class syntax is described as "syntactic sugar" because it does not introduce a new Object-Oriented inheritance model to JavaScript.
Under the hood, classes compile down to standard constructor functions and prototypal inheritance:
• The class declaration creates a constructor function.
• Methods defined in the class body are attached to the prototype object (Class.prototype).
• Inheritance (extends) sets up prototype chaining using Object.setPrototypeOf().
It provides a cleaner, cleaner syntax to write prototypes, but the underlying execution model remains unchanged.
12. Production Considerations
- • Strict Mode: Class bodies are automatically executed in strict mode. This prevents typical errors (like assigning values to read-only properties or creating implicit globals) by throwing errors instead of failing silently.