Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a constructor inherits another in ES6

Tags:

I have a situation where I need to check if a constructor (X) has another constructor (Y) in its prototype chain (or is Y itself).

The quickest means to do this might be (new X()) instanceof Y. That isn't an option in this case because the constructors in question may throw if instantiated without valid arguments.

The next approach I've considered is this:

const doesInherit = (A, B) => {   while (A) {     if (A === B) return true;     A = Object.getPrototypeOf(A);   }    return false; } 

That works, but I can't shake the sense that I'm missing some more straightforward way to check this. Is there one?

like image 695
Semicolon Avatar asked Jun 23 '15 03:06

Semicolon


People also ask

How does prototypal inheritance work?

The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects. It is a method by which an object can inherit the properties and methods of another object. Traditionally, in order to get and set the [[Prototype]] of an object, we use Object. getPrototypeOf and Object.

Does JavaScript follow inheritance?

JavaScript doesn't use classical inheritance. Instead, it uses prototypal inheritance. In prototypal inheritance, an object “inherits” properties from another object via the prototype linkage.

What is inheritance in JavaScript ES6?

The ES6 JavaScript supports Object-Oriented programming components such as Object, Class and Methods. Further in Classes we can implement inheritance to make child inherits all methods of Parent Class. This can be done using the extends and super keywords. We use the extends keyword to implement the inheritance in ES6.

What is prototype chaining in JavaScript?

That means all the objects in JavaScript, inherit the properties and methods from Object. prototype. This is called Prototype chaining. This is a very powerful and potentially dangerous mechanism to override or extend object behavior. Objects created using new keyword, inherit from a prototype called Object.


2 Answers

Because of the way instanceof works, you should be able to do

A.prototype instanceof B 

But this would only test inheritance, you should have to compare A === B to test for self-reference:

A === B || A.prototype instanceof B 

Babel example:

class A {} class B extends A {} class C extends B {}  console.log(C === C) // true console.log(C.prototype instanceof B) // true console.log(C.prototype instanceof A) // true 

instanceof is basically implemented as follows:

function instanceof(obj, Constr) {   var proto;   while ((proto = Object.getProtoypeOf(obj)) {     if (proto === Constr.prototype) {       return true;     }   }   return false; } 

It iterates over the prototype chain of the object and checks whether any of the prototypes equals the constructors prototype property.

So almost like what you were doing, but internally.

like image 56
Felix Kling Avatar answered Oct 18 '22 03:10

Felix Kling


There's also Object.prototype.isPrototypeOf(). Seems like a perfect use case, no?

Babel

class A {} class B extends A {} class C extends B {} console.log(C === C) console.log(B.isPrototypeOf(C)) console.log(A.isPrototypeOf(C)) 
like image 27
Oka Avatar answered Oct 18 '22 04:10

Oka