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
switch
statement I cannot implement the properinstanceof
logic. This way? No problem. - I can use domain-specific names of the methods. The method
do
is not exactly domain-specific, but we could use something likedrawOnCanvas
to 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?