Using the super Keyword in JavaScript Classes
A complete guide to the super keyword in JavaScript. Learn how super() works in constructors, how super.method() calls parent implementations, super in static methods, super in object literals, and common mistakes every developer should avoid.
The super keyword gives child classes access to their parent class. It has two distinct uses: super() to call the parent constructor, and super.property / super.method() to access parent properties and methods. Understanding how super works — and the rules around it — prevents a class of common inheritance bugs.
super() in the Constructor
When a class extends another class, its constructor must call super() before accessing this. super() invokes the parent constructor and is what creates and initializes the this object:
class Vehicle {
constructor(make, year) {
this.make = make;
this.year = year;
}
}
class Car extends Vehicle {
constructor(make, year, model) {
super(make, year); // Parent constructor runs first
this.model = model; // Now this is available
}
}
const car = new Car("Honda", 2022, "Civic");
console.log(car.make); // "Honda"
console.log(car.year); // 2022
console.log(car.model); // "Civic"The parent arguments flow through super() — pass exactly what the parent constructor expects.
Why super() Must Come Before this
In derived classes, this does not exist until super() has completed. The parent is responsible for creating the object:
class Base {
constructor() {
this.x = 10;
}
}
class Derived extends Base {
constructor() {
// ❌ this.y = 20; → ReferenceError: Must call super constructor before accessing 'this'
super(); // ✅ parent runs, this.x = 10 happens
this.y = 20; // ✅ now this is available
}
}
const d = new Derived();
console.log(d.x); // 10
console.log(d.y); // 20The engine enforces this: accessing this before super() in a derived constructor is a ReferenceError.
super.method() — Calling Parent Instance Methods
super.method() calls the parent class's version of a method, even if the child has overridden it:
class Formatter {
format(value) {
return String(value).trim();
}
}
class CurrencyFormatter extends Formatter {
constructor(currency) {
super();
this.currency = currency;
}
format(value) {
const cleaned = super.format(value); // Call parent's trim/String conversion
return `${this.currency}${Number(cleaned).toFixed(2)}`;
}
}
const usd = new CurrencyFormatter("$");
console.log(usd.format(" 42.5 ")); // "$42.50"This is the most common use of super — extending parent behavior rather than replacing it entirely.
Chaining super.method() Through Multiple Levels
In multi-level hierarchies, each super.method() call goes to the immediate parent:
class A {
greet() { return "Hello from A"; }
}
class B extends A {
greet() { return super.greet() + " + B"; }
}
class C extends B {
greet() { return super.greet() + " + C"; }
}
const c = new C();
console.log(c.greet()); // "Hello from A + B + C"
// C.greet → super.greet() → B.greet → super.greet() → A.greetsuper in Static Methods
Static methods can also call parent static methods using super.staticMethod():
class MathBase {
static double(n) { return n * 2; }
static square(n) { return n * n; }
}
class MathExtended extends MathBase {
static doubleSquare(n) {
return super.double(super.square(n)); // Uses parent static methods
}
static scale(n, factor) {
return super.double(n) * factor;
}
}
console.log(MathExtended.doubleSquare(3)); // double(square(3)) = double(9) = 18
console.log(MathExtended.scale(5, 3)); // double(5) * 3 = 30Note: In static methods, this refers to the class itself (or subclass). super in a static context refers to the parent class's static side.
| Context | super refers to |
|---|---|
| Instance method | Parent's prototype |
| Static method | Parent class (static side) |
| Constructor | Parent constructor |
super in Object Literals
super is not limited to classes — it also works in object literal methods via the [[HomeObject]] mechanism:
const animal = {
speak() {
return "Some sound";
}
};
const dog = {
__proto__: animal,
speak() {
return `${super.speak()}, specifically: Woof!`;
}
};
console.log(dog.speak()); // "Some sound, specifically: Woof!"Method shorthand syntax (e.g., method() {}) sets [[HomeObject]]; arrow functions and regular function expressions do not, so super only works in shorthand methods and class methods.
super vs this — The Key Difference
A frequent confusion point:
class Parent {
name = "Parent";
report() {
return `This: ${this.name}`;
}
}
class Child extends Parent {
name = "Child";
test() {
console.log(super.report()); // "This: Child" — this still refers to the instance
console.log(this.name); // "Child"
}
}
new Child().test();super.report() calls the parent's report method, but this inside that method still refers to the current instance (the Child instance). super affects which method body runs, not what this is.
Common Mistakes
Missing super() in Derived Constructor
class Animal { constructor(name) { this.name = name; } }
class Dog extends Animal {
constructor(name, breed) {
// super(name); ← Forgot!
this.breed = breed; // ❌ ReferenceError: Must call super before accessing 'this'
}
}Calling super() in a Non-Derived Class
class Base {
constructor() {
super(); // ❌ SyntaxError: 'super' keyword unexpected here
}
}super() is only valid in derived class constructors.
super Outside a Method
function test() {
super.toString(); // ❌ SyntaxError: super keyword outside a method
}super is only valid inside class methods (instance or static) or object literal shorthand methods.
Rune AI
Key Insights
- super() creates this: In derived constructors, super() invokes the parent, which allocates and initializes the this object — this is unavailable until super() returns
- super() must be called exactly once: More than once throws a ReferenceError; omitting it (when you have a constructor) also throws a ReferenceError
- super.method() runs the parent body with the same this: Calling super.method() from a child executes the parent's method, but this still refers to the child instance
- super works in static methods too: super.staticMethod() in a static context refers to the parent class's static method
- [[HomeObject]] enables super in methods: Method shorthand syntax attaches a [[HomeObject]] slot; arrow functions and regular function expressions do not have it and cannot use super
Frequently Asked Questions
Can I call super() multiple times in a constructor?
Does super() return a value?
What is [[HomeObject]] and why does it matter for super?
Does super work with mixins?
Conclusion
The super keyword has two forms: super() in constructors invokes the parent class, creates the this object, and must be called before this is accessed; super.name in methods references the parent's prototype, allowing child methods to extend rather than completely replace parent behavior. super works identically in static methods (targeting the static side of the parent) and in object literal shorthand methods. Understanding super fully requires understanding JavaScript class inheritance and the prototype chain it operates on.
More in this topic
OffscreenCanvas API in JS for UI Performance
Master the OffscreenCanvas API to offload rendering from the main thread. Covers worker-based 2D and WebGL rendering, animation loops inside workers, bitmap transfer, double buffering, chart rendering pipelines, image processing, and performance measurement strategies.
Advanced Web Workers for High Performance JS
Master Web Workers for truly parallel JavaScript execution. Covers dedicated and shared workers, structured cloning, transferable objects, SharedArrayBuffer with Atomics, worker pools, task scheduling, Comlink RPC patterns, module workers, and performance profiling strategies.
JavaScript Macros and Abstract Code Generation
Master JavaScript code generation techniques for compile-time and runtime metaprogramming. Covers AST manipulation, Babel plugin authorship, tagged template literals as macros, code generation pipelines, source-to-source transformation, compile-time evaluation, and safe eval alternatives.