JavaScript is like the father who overpampered and spoilt his son, and now the son blames his Dad for things he can't handle. When I was first introduced to JS, I was said, and I quote  "JavaScript is a very forgiving language." This epithet stuck with me forever. Indeed, JS lets you do stuff you cannot imagine with other popular languages (I do not speak for the ones I don't know).
But before blaming JS think for a second, WHY would you want to add a string and number? What's the meaning of subtracting two strings? Why would you want to assign a negative index in an array? (Wait, did I just say negative indices??👻 Boo! I will get to it.) Some of the answers are obvious to ardent JS users when they use it dayin and dayout. But for the rest of you out there, just don't do it until you see why!
Jokes aside, I present to you few more such playful insanities of JS. I had a fun time fiddling with them, hope you too. Enough said, let's dive in.
1. Math.min() and Math.max() Upsidedown
Most of us use these two functions in daytoday basis. It's easiest way to compare a set of N numbers. Let's see what happens when you call them without feeding any parameters. What do you think the output to the following be:
console.log( Number.POSITIVE_INFINITY > Math.min() ); //false
console.log( Number.NEGATIVE_INFINITY < Math.max() ); //false
//Damn Son!!
First reaction: You kidding me!
But let's go ahead and see what values are we comparing at first place.
console.log( Math.min() ); //Infinity
console.log( Math.max() ); //Infinity
Although this feels very counterintuitive to have min()
as +Infinity
and max()
as negative, I find an explanation very convincing...
Let's take Math.min()
.
We use it to find the minimum number from a set. When you call it with no parameters, it initializes a number with Maximum Possible Value. Then, when you compare your first finite number with this, it will always pick that number as minimum.
Imagine if Math.min()
was Infinity. No matter what you compare this with, it will always pick your Infinity. The function would fail!
When I have to write an algorithm to find a minimum of something. Say, a minimum Sum, or the smallest number in a dynamic array, or whatsoever, I always initialize my comparison variable with Math.min()
, so when I revisit it, I instantly know what I am intending to do! That is, find the MINIMUM.
Doesn't sound so counterintuitive now, does it? Simple logic Want to find the minimum of a lot? Initialize using min!
Needless to explain, the same logic goes with Math.max()
. To check if a number is maximum, we start comparing it with Infinity and climb all the way up.
Now that you know, you will find yourself using this so very often! Been there. Done that.
2. Identity Crisis of NaN (I am NotANumber!!)
What do you think is the typeof NaN?
console.log( typeof NaN );
//"number"
This one got me rolling on the floor. 🤣
Literally, the fullform of NaN is Not a number. And yet, here we are!
Contrary to the popular belief, NaN
is not a JS Keyword. It is merely a property of the global object Number, just like several others you would be aware of:
let x = Number.NaN; //NaN
let y = Number.NEGATIVE_INFINITY; //Infinity
let z = Number.MIN_VALUE; //5e324
let w = Number.MAX_VALUE; //1.7976931348623157e+308
NaN signifies quite a variety of scenarios. To enumerate a few:
 You did an operation not explained by Math. Example 0/0, Infinity/Infinity, Infinity * 0
 You are trying to convert a nonnumeric value to Number.
Example
Number('foo')
or+"foo"
 You challenged the finites of Computer Arithmetic and executed an operation far bigger than the bits could hold. Example
(3.3489324884 * 10e616) / (3.3489324884 * 10e616); //NaN
So, NaN does not always signify Notanumber, rather it's a way of saying
"You are trying to get a number beyond the understanding of your machine."
having understood NaN now, what would be output for this:
let x = (3.454*10e500)/(3.454*10e500);
console.log( x );
console.log( x === NaN );
YES! Although x is NaN, the comparison throws False. Could you try reasoning out why?
This question reminds me of a famous John Green quote:
"Some infinities are bigger than other infinities."
Anyways, if you are searching for an exact answer why this doesn't work and how else will you check for NaN, you will find the answer here.
Shhh, spoiler:
let x = NaN;
isNaN(x); //true
3. Who murdered my Array?
Prepare to get Bonkers! I urge you to open your Developers Console even before you start scrolling, you are going to need it.
let x = [10, 20, 30, 40, 50];
console.log( x.length );
x[1] = 0;
x[2] = 10;
console.log( x.length );
console.log( x );
Did JS just let me add negative indices to an array!!! 🔪🔪🔪
Before I start explaining, let's see what the output looks like?
If you notice, even after adding two more data to the array, x.length
remains as 5, although the array shows the newly added data.
Let's get our funda clear
Any nonprimitive data type in JS is treated as an Object. Let alone Arrays, Sets, Maps, even Functions are Objects. And any object is a set of keyvalue of pairs.
To understand what's happening in our use case here, let's for a second, forget that x is an Array, and treat it as an Object (which it is, since arrays are also objects). Now, let's try adding a function definition, or a new attribute to x:
x.foo = () => console.log('in x foo')
x.name = "James Dean";
console.log( x );
console.log( x.length );
x.foo();
console.log( x["name"] );
I hope you are trying this out onhands with me. You will get an x that looks like this:
Are you able to guess what's happening? The array length still remains as 5 but all other attributes are present just like in an Object. If you open up the __proto__
of x you will see Array, open it up one more hierarchy and you see Object. This is Prototype Chaining.
Since, only whole number indices are supported by the Array data structure, the rest of the keys are simply treated as keyvalue pairs of an Object.
You can simply invoke foo using x.foo()
or access the name
attribute using one of the two ways of accessing a JSON Object:

x.name
x["name"]
So what's with the negative indices?
They are also just a keyvalue pair like name
. Where the object x has
x["1"]
attribute value. It is only an illusion of negative index where as it's only a part of the x object and not the Array.
And there's your answer!!! 🦄
But before I end, I want you to try a couple more things and see what x looks like and what happens to the length:
x[5] = 90;
x[8] = 100;
//NOTE: We skipped index 6 and 7 altogether.
//What happens to the length?
console.log( x.length ); //9
console.log( x );
When you skip the whole number indices (the legit indices of an array), JS just creates EMPTY spaces an array index holding undefined data type. But the space gets reserved as a part of the array. And that's why the length increases to the maximum index. This is what it looks like:
AMAZING!!! Isn't it?
I absolutely adore JavaScript for it's Willy Wonka ways with data types and data structures. I have laughed out loud at some problems, I have pulled my brains out at others. But nevertheless, I hope this language never dies. Frameworks may come and frameworks may go, I hope Vanilla JS goes on forever.
I do hope you had fun trying out some examples from above. And I also hope, I atleast inspired a handful of you to open up your computers and get scripting! Do let me know if I went wrong somewhere or what you think about the article. Your response inspires me to write more! 🧐
Find the previous article of this series here.
See you soon! 👋
Top comments (0)