Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I substitute a class's prototype with another class's?

Given two classes where I want to give the methods of one to another:

class a {}
class b {say() {console.log('hello')}}
var foo = new a();

How come this works:

a.prototype.say = b.prototype.say;
foo.say();    //'hello'

But this doesn't?

a.prototype = b.prototype;
foo.say();    //foo.say is not a function

To be clear, I'm not asking how to give one class's methods to another, but why prototype behaves like this.

Bonus question: what's the difference between defining a method inside a class block and defining it by directly assigning it to the prototype?

like image 505
leinaD_natipaC Avatar asked Aug 23 '18 19:08

leinaD_natipaC


People also ask

What is the difference between __ proto __ and prototype?

The prototype property is set to function when it is declared. All the functions have a prototype property. proto property that is set to an object when it is created using a new keyword. All objects behavior newly created have proto properties.

What is prototype chaining?

The prototype of an object would also have a prototype object. This continues until we reach the top level when there is no prototype object. This is called prototype chaining or prototype chain in JavaScript. The properties defined on the prototype objects are also accessible to the object instance.

What is the difference between class-based and prototype-based?

The most important difference between class- and prototype-based inheritance is that a class defines a type which can be instantiated at runtime, whereas a prototype is itself an object instance.


1 Answers

The reason for this is that prototype on a class is a non-writable, non-configurable property:

class a {}
class b {say() {console.log('hello')}}

console.log(Object.getOwnPropertyDescriptor(a,'prototype'))

Non-writable means you can't reassign the property prototype and non-configurable means you can't change the property to make writable: true or delete the property.

The result is that this has no effect:

class a {}
class b {say() {console.log('hello')}}

a.prototype = b.prototype;
console.log(a.prototype === b.prototype)

But non-writable only means you can't change the value associate with the property a.prototype — it will always point to the same object — it doesn't mean that you can't add properties to that object. This is why you can still add a.prototype.say.

like image 60
Mark Avatar answered Sep 27 '22 23:09

Mark