Search code examples
typescriptinheritancecomparisonderived-classtypeof

Comparing instances of derived classes having the same parent class


I have two classes extendending the same parent class, like this:

class ParentClass{ ... }
class Son extends ParentClass{ ... }
class Daughter extends ParentClass{ ... }

I'd like to have code similar to this pseudocode:

a.getClass() === b.getClass(); 

which should only return true if both variables are instances of the same derived class (e.g. Son or Daughter in this example).


Solution

  • I'd like to have code similar to this:

    typeof a === typeof b
    

    which only returns true if both variables are instances of the same derived class (e.g. Son or Daughter in this example).

    No, that returns true if a and b are objects of any kind, including ones completely unrelated to ParentClass, because typeof will be "object" for any object, and of course, "object" === "object" is true.

    instanceof returns true if the left-hand operand's prototype chain contains the object referenced by the right-hand operands .prototype property, so instanceof will work as you describe you seem to want:

    a instanceof ParentClass === b instanceof ParentClass
    

    Live Example:

    class ParentClass { }
    class Son extends ParentClass { }
    class Daughter extends ParentClass { }
    
    const a = new Son();
    const b = new Daughter();
    
    console.log(a instanceof ParentClass === b instanceof ParentClass); // true
    
    const c = new Son();
    const d = new Map(); // Not a ParentClass subclass
    
    console.log(c instanceof ParentClass === d instanceof ParentClass); // false


    In a comment you've said:

    I'd like to find out if two variables are instances of the same derived class. My original question was worded very confusingly, so I edited it.

    Ah, then you'd want to use the constructor property in one of two ways. Either:

    1. To see if a is an instance of the same class as b or a subclass of b's class:

      a instanceof b.constructor
      
    2. To see if a is an instance of the same class as b:

      a.constructor === b.constructor
      

    The constructor property comes from the instance's prototype; by default, it's a reference to the cosntructor function the prototype object was originally attached to *(that is, Son.prototype.constructor refers to Son).

    Live example of #1:

    class ParentClass { }
    class Son extends ParentClass { }
    class Daughter extends ParentClass { }
    
    const a = new Son();
    const b = new Daughter();
    
    console.log(a instanceof b.constructor); // false
    
    const c = new Son();
    const d = new Son();
    
    console.log(c instanceof d.constructor); // true
    
    class SonSubClass extends Son { }
    
    const e = new SonSubClass();
    const f = new Son();
    
    console.log(e instanceof f.constructor); // true

    Live example of #2:

    class ParentClass { }
    class Son extends ParentClass { }
    class Daughter extends ParentClass { }
    
    const a = new Son();
    const b = new Daughter();
    
    console.log(a instanceof b.constructor); // false
    
    const c = new Son();
    const d = new Son();
    
    console.log(c instanceof d.constructor); // true
    
    class SonSubClass extends Son { }
    
    const e = new SonSubClass();
    const f = new Son();
    
    console.log(e.constructor === f.constructor); // false