0

I understand that in case of prototypal inheritance, the objects are linked together through a prototype chain. The inheritance is a "REFERENCE" to some other live object (instantiation).

Where as in case of class-based inheritance, classes (templates) are made to inculcate inheritance. Any sub-class instantiation "POSSESSES" an instance of a parent object.

But how does Javascript not implement "classical" inheritance with the ES6 syntax? With the ES6 class syntax, what you're doing is essentially creating templates. And upon the instantiation of an object, a separate live instance of the parent is made every time. Isn't this classical inheritance?

  • 4
    ES6 class syntax is mostly just a thin veneer over the actual underlying prototypical syntax. But really, where's the big difference to begin with? The mechanics of prototypical inheritance vs. classic are slightly different, but the end result is mostly the same. – deceze Jun 12 '19 at 13:07
  • 2
    And what exactly *is* "classical inheritance"? I've never heard anyone describe [tag:python]'s OOP as "prototypical", but it is really a lot closer to Javascript than to, say, Java. – deceze Jun 12 '19 at 13:09
  • So the ES6 syntax emulates "classical" inheritance on top of prototypal inheritance? Is there any significance to this "emulated" classical inheritance? – RogerBacon Jun 12 '19 at 13:10
  • 2
    @RogerBacon define "significance". It's syntactic sugar for the most part. – VLAZ Jun 12 '19 at 13:13
  • 1
    ES6 class syntax just provides a more familiar syntax for creating normal JS constructor functions. It does not attempt to alter the inheritance system of JavaScript. – msg45f Jun 12 '19 at 13:15
  • @msg45f So as far as I understand, when instantiating an object using the ES6 class syntax, a separate copy of parent does get instantiated and then linked to the object using prototypal chain? In essence, "classical" but done using prototypical linkage? – RogerBacon Jun 12 '19 at 13:22
  • @RogerBacon No, it's still a single prototype. You can test this easily by mutating the __proto__ of an instantiated object and still see those mutations on other objects created from the ES6 class. – msg45f Jun 12 '19 at 13:31
  • @RogerBacon using ES5 you'd have `function MyClass() {}` and when you do `new MyClass` you get an object with `.prototype` set to `MyClass.prototype`. In ES6 you have `class MyClass {}` and when you do `new MyClass` you get an object with `.prototype` set to `MyClass.prototype`. It's the same. You don't get a new instance of the parent object in either case - there is a single instance of the *prototype* object. – VLAZ Jun 12 '19 at 13:37
  • Related: [Will JavaScript ever become a 'proper' class based language?](https://stackoverflow.com/q/24785746/1048572) – Bergi Jun 18 '19 at 14:29

2 Answers2

3

Yes, class is intended to behave like classes in other languages, thus it looks like "classical inheritance". Under the hood it is still prototypal inheritance though.

class Animal {}
class Human {}

const me = new Human;

Object.setPrototypeOf(me, Animal.prototype);
console.log(me instanceof Animal); // true
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
3

No, ES6 class syntax does not implement classical inheritance. The methods of the class are still placed on a .prototype object that is linked to the instances through prototypical inheritance.

There is no "templating" going on either. Attributes are not declared beforehand, the shape of instances is not fixed. They are just plain objects all along, and their properties get created in the constructor.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Pardon me but how is there no "templating" per se? I am using the class syntax to blueprint a possible instantiation of an object, much like I'd do in, lets say, C++. ES6 class seems to emulate the behavior of classical inheritance. – RogerBacon Jun 12 '19 at 13:19
  • @RogerBacon What aspects of the instantiation exactly are templated? The number, names and types of properties can be dynamic (unlike in C++). – Bergi Jun 12 '19 at 13:23
  • What I'm understanding is: the instantiation is done as a plain empty object without following any sort of "templates" but then when going through the constructor, additional properties may or may not be defined/initialized? Am I right? – RogerBacon Jun 12 '19 at 13:26
  • @RogerBacon Yes, that's right. And how do you feel about `function factory(a, b) { return {a, b, c:3, method() { return this.a + this.c;}}; }` - is that a class like in other languages as well, since it serves as a template for object instantiation? – Bergi Jun 12 '19 at 13:27
  • Apart from the implementation details, it really does emulate classical inheritance, right? Since the parent's instance is just for that one particular instance (object) alone and is "referenced" by it alone? – RogerBacon Jun 12 '19 at 13:28
  • No, after your explanation, I don't think its a class, as in its not a proper template for instantiation. The instantiation gets done as a plain object, with additional properties initialized. There is no "fixed" shape/size of an object. – RogerBacon Jun 12 '19 at 13:32
  • @RogerBacon If we ignore syntax and implementation details, classical inheritance can be *emulated* in every turing-complete programming language. And yes, ES6 `class` syntax was made specifically to enable the "class pattern" that is so popular and useful. But it does not implement classical inheritance (with fixed shapes, static method dispatch etc), it keeps all the power and freedom of Javascript's prototypical inheritance - even if in 99% we do not need to harness that power. – Bergi Jun 12 '19 at 13:35