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.

JavaScriptintermediate
11 min read

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:

javascriptjavascript
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:

javascriptjavascript
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); // 20

The 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:

javascriptjavascript
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:

javascriptjavascript
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.greet

super in Static Methods

Static methods can also call parent static methods using super.staticMethod():

javascriptjavascript
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 = 30

Note: In static methods, this refers to the class itself (or subclass). super in a static context refers to the parent class's static side.

Contextsuper refers to
Instance methodParent's prototype
Static methodParent class (static side)
ConstructorParent constructor

super in Object Literals

super is not limited to classes — it also works in object literal methods via the [[HomeObject]] mechanism:

javascriptjavascript
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:

javascriptjavascript
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

javascriptjavascript
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

javascriptjavascript
class Base {
  constructor() {
    super(); // ❌ SyntaxError: 'super' keyword unexpected here
  }
}

super() is only valid in derived class constructors.

super Outside a Method

javascriptjavascript
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

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
RunePowered by Rune AI

Frequently Asked Questions

Can I call super() multiple times in a constructor?

No. Calling `super()` more than once throws a `ReferenceError`. It should be called exactly once, before any use of `this`.

Does super() return a value?

Yes. In rare cases where the parent constructor explicitly returns an object (not a primitive), `super()` returns that object and it becomes `this`. In normal cases the return value of `super()` is the new instance.

What is [[HomeObject]] and why does it matter for super?

`[[HomeObject]]` is an internal slot set on methods when they are defined using shorthand syntax in a class or object literal. It determines which prototype `super` looks up when resolving `super.method()`. Without `[[HomeObject]]`, `super` cannot determine where to look. Arrow functions and regular function expressions do not get `[[HomeObject]]`, so they cannot use `super`.

Does super work with mixins?

Yes. Because mixins are function-based class expressions (`const M = (Base) => class extends Base { ... }`), `super` inside the mixin method refers to whatever `Base` was at mixin application time. The chain works correctly. See [how prototypal inheritance works in JavaScript](/tutorials/programming-languages/javascript/how-prototypal-inheritance-works-in-javascript) for mixin details.

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.