How to use the switch statement when checking whether some object is an instance of some class.
If you don’t like long reading, skip to solutions: constructor based and DSL based.
Imagine code like this:
|
|
This code works just fine and as expected (try it). But isn’t there a better way? Without multiple if statements? This is where the switch statement comes to play. We usually use the switch statement when we have a few fixed amounts of values and we want to do different things for different values. For example:
|
|
The problem with the shape instanceof Point is that it cannot be simply transformed into the switch statement. This does not work:
|
|
Why? The interpreter would simply check whether the shape variable equals the Point variable and that is not the case. It does not check if shape is an instance of Point. It checks if shape is Point.
Use .constructor
There is a hack. You can check whether the constructor property equals the class. The constructor property returns a reference to the Object constructor function that created the instance object. Roughly speaking, it contains a reference to the Class.
|
|
It works! (try it) But there is a significant drawback:
It checks if shape’s constructor equals the given class. It does not check if it is an instance of this class – it does not work well with “inheritance”. If we add another shape called RedCircle that extends Circle, the switch statement fails to recognize it as a Circle:
|
|
It prints “Unknown object…”. (try it)
Not that TypeScript does infer the type. Let’s add property radius to the Circle class. We should be able to read the property is we check the shape is actually a Circle:
|
|
And it works (try it).
Write Your Own Mini-DSL
Maybe switch syntax is not the answer. Maybe no syntax is the answer. Maybe mini-DSL is the answer. DSL stands for domain-specific language. We can simply ignore the switch statement and we can even ignore the if statement. We can write our own function with some nice API to check whether the shape variable is Circle or not. What would you say to this syntax:
|
|
Is it readable? I’d say yes. Don’t like the method names? Use any better naming you like! That is the magic. And how to implement it? I usually write it using a few nested functions:
|
|
If it gets too big, I refactor it (try it). Why do I like it?
- It reads nicely!
- I can implement any logic I want. With the
switchstatement I cannot implement the properinstanceoflogic. This way? No problem. - I can use domain-specific names of the methods. The method
dois not exactly domain-specific, but we could use something likedrawOnCanvasto be more specific. - We can implement additional logic there.
What are the drawbacks? As far as I know, it’s not possible to implement lazy evaluation: all of the conditions are always evaluated. That should not be an issue in most cases.
Do you have any better ideas?