TypeScript – how to make JavaScript bearable – Part 1

I vaguely remember some talk about JavaScript that called it write-only language. Truth be told it was probably about some other, even more, obscure and ‘unconstrained’ language (and by ‘unconstrained‘ mean one with several different solutions for a particular problem), but it fits JavaScript pretty nicely.

There is a hilarious video about it, which every aspiring JavaScript programmer should see – JavaScript Wat.

But if for whatever reason you’re more inclined to reading, let me show you just a few of many ‘gotcha’ that you may encounter when dealing with it.

Parameter passing

Let’s start with a fairly simple example, of array mapping:

['1', '2', '3'].map(parseFloat)

The output will be (obviously):

[1, 2, 3]

So where is the surprise? You might ask – try the same thing with parseInt

[1, NaN, NaN]

Why is that? You might wonder – those are clearly numbers and should be parsed properly. Moreso if you actually execute parseInt on a single string it will return the proper value

parseInt('2')

In this case, function map is up to some mischief. In C# (and probably most other programming languages) it is only possible to call group expression if the called method accepts only one argument. JavaScript, however, unlike most programming languages allows you to call methods with insufficient or even extra parameters and all potential errors will be suppressed by language.

We called map with an implicit function call. In that mode map calls function with three arguments (instead of intuitive one):

  1. reference current element
  2. index of the current element in the array
  3. reference to the original array

Therefore those two syntaxes are equivalent:

['1', '2', '3'].map(parseInt)
['1', '2', '3'].map((e, i, a) => parseInt(e, i, a))

What parseInt does with those additional arguments? It only accepts first two and discards the third (again suppressing any error). The first argument is (obviously) string to parse, the second one is radix – a number (from 2 to 36) that represents the numeral system to be used). So passing [‘1’, ‘2’, ‘3’] array into parseInt with implicit parameter call we will receive:

  • 1 – because radix of 0 is invalid, this error is suppressed again and result for standard parseInt(‘1’) is returned
  • NaN – because… despite radix of 1 being invalid, it’s still taken into account and ‘2′ is not present in.. mono..ary (just like binary, but instead of 0 and 1, you only have 1)?
  • NaN – because ‘3’ is not valid in binary (radix of 2)

In conclusion: Yey JavaScript! Never ever use implicit method calls!

No need for a variable declaration!

Most programming languages would require us to declare all used variables in advance. When I was writing my first programs I found this very annoying, but after those programs reached a hundred lines I was more understanding.

Usual problem that I encounter when writing code looks something like this:

var someobscurevariable = this.getSomeResult();
if (someObscureVariable != 2) {
    return true
} else { 
    return false
}

Currently, most IDE’s will give you a notification, that someObscureVariable is not declared and probably checking it against anything might not be a good idea, but JavaScript will take that knowledge to its grave.

This behaviour is especially annoying if two places when you assign and check variables are screens apart (which – let’s admit can happen in some single page applications that we might happen to write using jQuery)

Calling external libraries

Last annoyance (for today) that haunts me is calling an external library with magic parameters. Take for example method such as this:

function normalizeBrackets(stdoff, arr, itr, cmpcallback, donecallback)

Usually, when using a function like this with strongly typed languages all of those parameters would have types (and hopefully better names). Unfortunately, it’s usually not the case when calling JavaScript libraries (which I’ve encountered so far, but I concede that I don’t have much experience with those, as I tried to limit my exposure to a wonderful world of front-end up to this point). Usually, there is a documentation attached to such library, which will be quite helpful (or no-one will actually use the library in the first place), but having strong types might mitigate this problem at all.

As a conclusion I would like to quote, my esteem colleague, whose words of wisdom can bring joy and hope, even during most tedious debugging sessions:

“We put a single quotes in JavaScript to remind us that it’s not a real programing language.”
— Vivasvan Paranjape

And if you say ‘Hey! You put single quote in SQL as well’ – well… I would stand by this quote all the same.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s