Typescript: What’s This!?
Here’s a little innocuous looking typescript:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | export default class MyClass { public asStrings( array: Array<SomeObject>, // array to turn to string objectReader: SomeObjectReader, // can extract a string from a SomeObject ) : string[] { const suffix = this .getSuffix(); return array.map(objectReader.readStringFromObject) .map(str => str + suffix); } private static getSuffix() : string { return `_${ new Date().getTime()}`; } } |
Let’s quickly understand what the above code is trying to do. It’s got a SomeObjectReader
object that it can use to pull a string out of a SomeObject
. It has an array of objects as input and it’s going to convert them all to string
and suffix them all with a timestamp of some sort.
The static
function to get the suffix should be static as it doesn’t rely on object state.
The asStrings
function also could be static, but let’s ignore that for the moment as that’s not quite the focus of this discussion.
The above code has a minimum of two bugs!
You Can’t Use this
to call a static
function
Why my compiler let me do this is anyone’s guess. The getSuffix
function must be called via the class name – MyClass.getSuffix()
.
I’ve just dropped a version of code into our dev environment that passed through all stages of compilation and test, yet still carried this bug. What a gotcha!
Functional Programming with this
is Not Neat
In general we learn that x => myFunc(x)
as a lambda in JavaScript can better be expressed as myFunc
. This compares with Java where we use function references in place of full lambdas wherever possible.
So in the above code, the array map
function is written .map(objectReader.readStringFromObject)
which to the untrained eye (in other words, me) looks like we’re asking the readStringFromObject
function on the particular instance of the object reader to be called within the map
operation.
Is the above the equivalent of .map(obj => objectReader.readStringFromObject(obj))
?
No.
If the objectReader
is an instance of a class that uses this
as part of its operation, then this
doesn’t actually mean what you might hope it would mean in the more terse form. In the latter form, it works every time. In the first form, it might work, but it probably won’t.
What’s This?
In JavaScript, this
is a relatively weak concept to begin with. In TypeScript it’s not practically any weaker, but it seems weaker as TypeScript gives us the illusion of concrete types and objects a lot more than its underlying transpiled code.
Aaagh!
Published on Java Code Geeks with permission by Ashley Frieze, partner at our JCG program. See the original article here: What’s This!? Opinions expressed by Java Code Geeks contributors are their own. |