ES6 Classes: Prototype Sugar
MedES6 classes are primarily syntactic sugar over JavaScript's existing prototype-based inheritance. The class syntax makes it easier to create constructor functions and manage prototypes, but under the hood, the same prototype mechanism is still at work. Understanding what class desugars to helps demystify how classes actually work in JavaScript.
Interactive Visualization
Classes are Syntactic Sugar over Prototypes
ES6 Class Syntax
1class Animal {2 constructor(name) {3 this.name = name4 }5 speak() {6 console.log(this.name + " speaks")7 }8}
Prototype Reality
1// Exact equivalent using prototypes:2function Animal(name) {3 this.name = name4}56Animal.prototype.speak = function() {7 console.log(this.name + " speaks")8}
ES6 class syntax: A clean, familiar way to define a constructor and methods.
1 / 5
Key Insight: Class syntax is syntactic sugar - both create the same prototype chain. Methods go on prototype, instance data goes on the instance.
Key Points
- class is syntactic sugar over constructor functions and prototypes
- constructor() method becomes the constructor function
- Methods are added to Class.prototype
- static methods become properties on the constructor
- typeof Class === "function"
- Class.prototype is the prototype for instances
Code Examples
Class Desugaring
// ES6 Class class Person { constructor(name) { this.name = name; } greet() { return "Hello, I'm " + this.name; } static species() { return "Homo sapiens"; } } // Desugars to: function Person(name) { this.name = name; } Person.prototype.greet = function() { return "Hello, I'm " + this.name; }; Person.species = function() { return "Homo sapiens"; }; // They are essentially the same! console.log(typeof Person); // "function"
Classes desugar to constructor functions with prototype methods.
Prototype Chain with Classes
class Animal { speak() { return "Some sound"; } } class Dog extends Animal { speak() { return "Woof!"; } } const dog = new Dog(); // The prototype chain: // dog → Dog.prototype → Animal.prototype → Object.prototype → null console.log(dog instanceof Dog); // true console.log(dog instanceof Animal); // true console.log(dog instanceof Object); // true // Same chain as manual prototype setup!
extends sets up the same prototype chain as Object.create() manually.
Methods on Prototype
class Counter { constructor() { this.count = 0; } increment() { this.count++; } } const c1 = new Counter(); const c2 = new Counter(); // Methods are shared on prototype console.log(c1.increment === c2.increment); // true // Same as: // Counter.prototype.increment = function() { ... } // This is efficient - one method object shared by all instances
Class methods are added to the prototype, shared across all instances.
Common Mistakes
- Thinking classes are not based on prototypes
- Not realizing typeof Class is "function"
- Thinking classes provide true privacy (private fields are newer)
Interview Tips
- Know that classes are syntactic sugar
- Be able to desugar a simple class
- Understand the prototype chain is the same
- Know that methods are shared on prototype