typescriptconstructorobject-comparison

TypeScript: Are there any other ways to detect that two object instantiated from similar class?


Is it a right way in typescript to detect that two object instantiated from similar class without instanceof operator?

abstract class CommonText {}
class BoldText {} extends CommonText
class ItalicText {} extends CommonText

const someBoldText = new BoldText("I like");
const anotherBoldText = new BoldText("cookies");
const italicText = new ItalicText("cursive");

//Comparison
if(someBoldText.constructor === anotherBoldText.constructor) {
  // Run operation
}
if(someBoldText.constructor === italicText.constructor) {
  // Should not be executed
}

It works fine but it`s a little bit ugly and I feel that there is a better way to do this.

Subquestion: Could you please explain me what exactly is compared in this case? Is it a pointers? Or signatures?

I am trying to create WYSIWYG editor using typescript and Vue.js as project to learn typescript. General idea is to recreate common browser behaviour with custom handlers. I have stoped on text styling and all works good, but there is a problem with data optimistaion which concludes in siblings which have the same style. For example: Scheme. So, when two object have same styling they should be merged into one.


Solution

  • You can read the thorough explanation here, but in short:

    The constructor property returns a reference to the Object constructor function that created the instance object. Note that the value of this property is a reference to the function itself, not a string containing the function's name.

    For objects created with the new SomeClass(...) syntax, the .constructor field would be SomeClass. Since JavaScript works with references (for non-primitives like booleans), that's a reference. You're thus checking whether both values were instantiated using the same class.

    That article also mentions the .constructor field can be overwritten and such, so you can make it whatever you want. The instanceof operator actually traverses your object's prototype chain, although it uses the .constructor property of the right-hand side value.


    For your use case, I'm not sure whether using classes for italic/bold is a great idea. At least not if you don't allow nesting styled text inside styled text. What if you want to format text both italic and bold? What if you want green bold text in the middle of red (bold) text? It might be better to have a generic StyledText class that has a set of (CSS?) properties, such as whether it's bold/italic, the text size/color, etc. You can then merge sequential StyledText objects with the same style.