neoan

Posted on

# The humor of JavaScript

As the year marks its end and we are therefore exposed to the yearly "What to use in 2024" click-bait articles, let's instead amuse us with some oddities of JavaScript.

## Numbers

You can't divide by zero. But why not? If I divide 1 by smaller and smaller fractions, I'll be getting higher and higher numbers nearing infinity. So eventually we'd end up at infinity? Not so fast. If we "came from the other side" towards zero, we'd approach negative infinity when getting to zero:

``````const a = 1/0.0001; // 1,000
const b = 1/0.000001; // 100,0000

const c = 1/-0.000001; // -100,0000
const d = 1/-0.0000001; // -1,000,0000
``````

So what does JavaScript do when dividing by zero? "NaN" maybe? Nope, it goes for infinity.

``````console.log(1/0) // Infinity
``````

Interesting. That means that the type of 1/0 must be infinity? Nope, it's NaN (Not a number).

``````console.log(typeof 1/0) // NaN
``````

Okay, so infinity doesn't seem to be a type, then? Let's test:

``````console.log(typeof Infinity) // number
``````

Wait a second, you think? If infinity is a number and 1/0 is infinity, why is the type of 1/0 not a number (NaN)? Well, let's explore:

``````console.log(typeof NaN) // number
console.log(NaN === NaN) // false
``````

Confused, yet?

## Objects

What's so nice about having no type safety is that we can be quick & dirty. So dirty indeed, that nearly every company will insist on Typescript to avoid almost impossible to find bugs. Let's examine the following code.

``````let myObject = null;

function getFromBackend(){
fetch('/api/object').then(j => j.json()).then(result => {
// result: {a: "b"}
myObject = result;
})
}

// SpongeBob narrator: ..several hours later

// Is our variable myObject filled?
function checkIfValid(){
if(typeof myObject === 'object'){
// do something
}
}

``````

Seems logical to a beginner, but here's the culprit

``````console.log(typeof null) // object
console.log(typeof null === typeof {}) // true
``````

But then again, we all know objects aren't object anyway, right?

``````console.log({} === {}) // false
``````

## OMG, what a language

Using the type-safe comparison (===) is therefore a must, as otherwise the nightmare would be so much worse:

``````const array = []
console.log(array == false) // true
console.log(array === false) // false
``````

There are even books about JavaScript oddities, as this list could go on for a while. But I guess we'd rather go on reddit to bash on PHP so Santa doesn't put us on the naughty list ;-)

Comment deleted

neoan

You misinterpreted my intended tone if you think I am "bashing JavaScript", a language I use on a daily basis. But humor is a good way to learn and face frustration.

Longevity

First of all, that's not really true for JavaScript. Some scripts designed for some 90s version of IE might use "Pre-ECMA, only works in this specific browser and version" tweaks that simply crash today. But leaving that aside, endless backwards compatibility introduces almost as many cons as pros when it comes to security and growth of a language. Think of markup languages like CSS or HTML. Do you really think if the web needed to be started from scratch this is how we would construct webpages today? Don't you see how we just build tool on top of tool to make these "documents" interactive masterpieces?

The "choice" for Infinity was driven by float allocation limits, not by concerns about errors (after all, it's easy to avoid and test).

Your absolutely correct about the `typeof 1/0`. Like many other examples I used, knowing what actually happens while the interpreter hoists & parses clears up some of the confusion.

However, some minor details: NaN is a global property, only `{}` actually creates an instance. Likewise, many loosely typed languages kept a difference between type safe and simple comparators. Not for backwards compatability, but because sometimes the difference comes in handy (if it's nothing, do you always need to know if it's null, undefined, or zero?)

I find your last paragraph unnecessarily hostile for a comment on an obviously light-hearted take. I don't know why my words triggered you so much, but I recommend not reading watercoolers as some kind of attack.

Kaamkiya

I completely agree. This is, without a doubt, the worst-built language ever. I even wrote an entire article about why I hate it.

neoan

Well, there's some charm in dirty languages. It makes functionality less verbose while allowing you to write clean, predictable code if you now what you are doing.

Kaamkiya

That's true.