In a JavaScript class, what is the difference between `super(...)` and `super.someMethod()`, and where is each one allowed to appear?
answer
- one constructs, one looks up
- only one place accepts the call form
- the receiver stays the current instance
- this.method() inside an override recurses
- statics have their own parent link
basics
~20 ssuper(...) invokes the parent constructor and is legal only inside the constructor of a class written with extends. super.someMethod() calls the parent's version of a method with the current instance as this, and is legal in any method or accessor.
solid answer
~40 sThey are two different syntactic forms that happen to share a keyword. `super(...)` is the **super call**: it runs the parent constructor and initialises `this`. It is legal in exactly one place — the constructor of a class declared with `extends` — and writing it in a base class constructor or an ordinary function is a `SyntaxError`. `super.someMethod()` is a **super property access**: it looks the name up starting from the parent, then calls it with the current `this` still bound, which is how an override wraps the behaviour it is replacing. That form is legal in any concise method, getter, setter or static method, including in a class with no parent at all, where it simply reaches `Object.prototype`. You cannot use either form in a function expression assigned to a property.
code
javascript · 14 linesclass Animal {
constructor(name) { this.name = name; }
speak() { return `${this.name} makes a sound`; }
}
class Dog extends Animal {
constructor(name) {
super(name); // the super call: runs Animal's constructor
this.legs = 4;
}
speak() {
return super.speak() + ' (a bark)'; // the super property
}
}
console.log(new Dog('Rex').speak()); // Rex makes a sound (a bark)go deeper
Be able to write both forms correctly: super(args) first in a subclass constructor, and super.method() inside an override to reuse the parent's behaviour without recursing.
Explain the legality rules — the call form only in a derived constructor, the property form in any method definition including statics and parentless classes — and why the receiver stays the current instance.
Bring the failure modes: infinite recursion from this.method() in an override, SyntaxError in function expressions, and why super.x before super() in a constructor still throws.
Discuss when a base class should expect subclasses to chain through super at all, since a required super call in an overridable method is an unenforceable contract that makes the base class fragile.
## One keyword, two forms The grammar treats `super` as two separate productions, and the rules differ for each. ### The super call: `super(...)` This one constructs. It finds the parent constructor — the prototype of the constructor currently running — invokes it, and binds the resulting object as `this` in the derived constructor. It is a statement about *object creation*, so it is legal in exactly one position: inside the constructor of a class declared with `extends`. ```js class Animal { constructor(name) { this.name = name; } } class Dog extends Animal { constructor(name) { super(name); // runs Animal's constructor this.legs = 4; } } ``` Everywhere else it is a `SyntaxError`, caught before the code runs: - in the constructor of a class with no `extends` clause; - in a normal method, even of a derived class; - in a standalone function. If a derived class declares no constructor, the engine supplies `constructor(...args) { super(...args); }`, so the call still happens — you just did not write it. ### The super property: `super.x` This one looks up. `super.speak()` starts the search at the parent of the object the method was defined in, finds `speak` there, and calls it with the current `this`. That last part is the whole point: the parent's code runs against the current instance, so it sees the subclass's own state. ```js class Animal { speak() { return `${this.name} makes a sound`; } } class Dog extends Animal { speak() { return super.speak() + ' (a bark)'; } } new Dog(); // this.name inside Animal#speak is the Dog's name ``` Without it, calling `this.speak()` inside the override would call the override again and recurse until the stack overflows — a classic first-week bug. The property form is legal much more widely than the call form: - instance methods, getters and setters; - static methods, where it reaches the parent **class**'s statics rather than the parent's prototype; - concise methods of ordinary object literals, not only classes; - a class with no `extends` at all, where the parent is `Object.prototype`, so `super.toString()` works. It is also **not** limited to reading. `super.x = 1` performs a set that starts its lookup on the parent — relevant when the parent defines a setter — though the property lands on `this`, not on the parent. ### Where neither form works Both forms need the surrounding function to be a *method definition*. A function expression assigned to a property is not one: ```js const obj = { greet: function () { return super.greet(); } }; // SyntaxError ``` An arrow function is a special case for the property form: it has no `super` of its own but inherits the enclosing method's, so `super.speak()` inside a callback written as an arrow inside a method is fine. ## The ordering interaction The two forms meet in one place. Because `super.x()` calls the parent method with `this` as receiver, and `this` does not exist before the super call, a derived constructor cannot use the property form before the call form: ```js class Dog extends Animal { constructor(name) { super.speak(); // ReferenceError: this is not initialised yet super(name); } } ``` So the ordering rule you learn for `super(...)` also constrains `super.x` inside constructors. ## How to answer this crisply Say: "`super(...)` runs the parent constructor and only exists in a derived constructor; `super.method()` calls the parent's version of a method with the current `this` and works in any method, including static ones and even in a class with no parent." Then give the recursion example — `this.speak()` versus `super.speak()` inside an override — because it shows you know *why* the property form exists rather than just where it is legal.
- What happens if an overriding method calls this.someMethod() instead of super.someMethod()?It calls itself. Property lookup on `this` finds the subclass's own override first, so the method re-enters immediately and blows the stack with a `RangeError`. `super.someMethod()` exists precisely to start the lookup one level above the defining class, so the parent's implementation runs against the same instance.
- Is super.toString() legal in a class that has no extends clause?Yes. The property form only needs a parent to look up on, and for a class without `extends` the instance methods' home object is the class's `.prototype`, whose prototype is `Object.prototype`. So `super.toString()` reaches the built-in implementation. Only the super *call* form requires an `extends` clause; writing `super()` in a base constructor is a `SyntaxError`.
- What does super refer to inside a static method?The parent class object, not its prototype. `extends` sets the subclass constructor's own prototype to the parent constructor, so a static method's `super.create()` finds the parent's static `create` and calls it with `this` still bound to whichever class the call went through — which is what makes inherited static factory methods produce the right subclass.
saying these in an interview costs you the question
- Says super() can be called from any method
- Thinks this.method() inside an override calls the parent
- Believes super.method() runs with the parent as this
- Claims super is unavailable in a class without extends
- Assumes super works inside any function in a class body