2

I am trying to understand the difference between Prototypal Inheritance and Classical Inheritance in Javascript. I came across some articles claiming The abstraction level for prototypal inheritance is never deeper than 1, but I don't understand why. Is that because the last inherited prototype has access to methods or properties of all its ancestors, whereas classical inheritance only has access to its last ancestor?

An example of accessing methods from all ancestors:

Simple graph to show inheritance:

Human ---> Zombie ---> ZombieBoss

Code

function Human(name, hp){
  this.name = name
  this.hp = hp
}

Human.prototype = {
  sleep: function (){
    this.hp += 50
    console.log('human recovered')
  },
  constructor: Human
}

function Zombie(name, hp){
  Human.call(this, name, hp)
}

Zombie.prototype = {
  ...Human.prototype,
  sleep: function (){
    this.hp += 100
    console.log('zombie recovered')
    Human.prototype.sleep.call(this)
  },
  constructor: Zombie
}

function ZombieBoss(name, hp){
  Zombie.call(this, name, hp)
}

ZombieBoss.prototype = {
  ...Zombie.prototype,
  sleep: function (){
    this.hp += 500
    console.log('zombie boss recovered')
    Human.prototype.sleep.call(this) //Method from ancestor's ancestor can be accessed as well. Which is not possible with super()
    Zombie.prototype.sleep.call(this) //Method from last ancestor 
  },
  constructor: ZombieBoss
}

const king = new ZombieBoss('king', 1000)
king.sleep() //hp should be 1700

If this is not the only reason, what are the remaining reasons for that? It would be great if there are some simple examples.

John Winston
  • 1,260
  • 15
  • 30

1 Answers1

1

It's a complicated way of saying: "In JavaScript, everything is a concrete object that exists in the JS engine, not an abstraction."

This is important! It means that Generalizations (like the overarching Shoe concept) are just other Objects. With Classical Inheritance, Generalizations are abstractions of abstractions of abstractions... all the way down to the most recent descendant.

The abstraction level here is never deeper than 1; The only abstraction that occurs with Prototypal Inheritance is the abstraction away from real-world things.

So, in his way of putting things, the only abstraction is:

JavaScript object <----- real world object that the JavaScript object represents

regardless of what other JS objects the JS object in question has as an internal prototype.

The way he's looking at things:

Human ---> Zombie ---> ZombieBoss

doesn't really matter, since each of those are concrete objects that exist in the interpreter, and each are one step away from an possible real-world object that those JS objects each represent.


On a separate note, your code is not implementing prototypal inheritance correctly:

Zombie.prototype = {
  ...Human.prototype,
  sleep: function (){
ZombieBoss.prototype = {
  ...Zombie.prototype,
  sleep: function (){

Your method above can help avoid code repetition, but each of those objects: Human.prototype, Zombie.prototype, and ZombieBoss.prototype all have an internal prototype of the same object: Object.prototype. The prototype chain you're implementing is

Object.prototype -> Human.prototype 
Object.prototype -> Zombie.prototype 
Object.prototype -> ZombieBoss.prototype 

If you want the prototypes to inherit from each other and get to what you were probably trying to do, you must use Object.create:

Zombie.prototype = Object.create(Human.prototype);
Zombie.prototype.sleep = function() {
  // ...
ZombieBoss.prototype = Object.create(Zombie.prototype);
// ...
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • I now understand why using `Object.assign()` is not the right way to chain prototype. If so, is it possible to to inherit multiple prototype in the same level? For example, can AB be created by inheriting A and B in the same level? Can I make AB inheriting A and B, without making A inherit B or B inherit A? – John Winston Mar 11 '21 at 08:04
  • Not in any reasonable fashion. https://stackoverflow.com/questions/9163341/multiple-inheritance-prototypes-in-javascript – CertainPerformance Mar 11 '21 at 13:51