In JavaScript, you have probably used the super keyword to invoke a superclass’ constructor:

class Hero {
constructor(name, level) {
this.name = name;
this.level = level;
}
}

class Warrior extends Hero {
constructor(name, level, weapon) {
super(name, level); // Invoke superclass' constructor
this.weapon = weapon;
}
}

You may have even used it to access properties and methods on the superclass:

class Hero {
constructor(name, level) {
this.name = name;
this.level = level;
}

greet() {
return `As a hero, ${this.name} says hello.`;
}
}

class Warrior extends Hero {
constructor(name, level, weapon) {
super(name, level);
this.weapon = weapon;
}

greet() {
let greeting = super.greet(); // Invoke method on superclass
greeting += `\nAs a warrior, ${this.name} says "take no prisoners!"`;
return greeting;
}
}

But did you know that you can use it in a method definition on an object literal?

let heroProto = {
greet() {
return `As a hero, ${this.name} says hello.`;
},
};

let warriorProto = {
__proto__: heroProto,
greet() {
let greeting = super.greet(); // Invoke method on prototype
greeting += `\nAs a warrior, ${this.name} says "take no prisoners!"`;
return greeting;
},
};

let warrior = {
__proto__: warriorProto,
name: "Bjorn",
level: 1,
weapon: "axe",
};

Note that it has to be a method definition. The old-school syntax of assigning a property to a function does not work:

let heroProto = {
greet() {
return `As a hero, ${this.name} says hello.`;
},
};

let warriorProto = {
__proto__: heroProto,
greet: function () {
let greeting = super.greet(); // SyntaxError
greeting += `\nAs a warrior, ${this.name} says "take no prisoners!"`;
return greeting;
},
};

let warrior = {
__proto__: warriorProto,
name: "Bjorn",
level: 1,
weapon: "axe",
};

Why? Method definitions are not just a shorthand. They also have semantic differences. This makes method definitions in object literals more consistent with method definitions in classes. Another example is that method definitions cannot be used as constructors, but properties assigned to functions can.


I borrowed the Hero and Warrior classes from Tania Rascia’s excellent post, Understanding Prototypes and Inheritance in JavaScript. I shared an updated version of her post a couple of weeks ago, with a few modern niceties.