Give sense to nonsense series: more weird JS explained

Alessandro Merola
salt&pepper
Published in
3 min readJun 2, 2021
“Photo by Caspar Camille Rubin on Unsplash”

“Why?! Why are you giving me this output?! That makes no sense!” — Here we go again

Welcome to the second part of the “Give sense to nonsense series”! If you missed the first article, you can find it here.

Now take a deep breath and get ready for more weird JS.

Math.min() and Math.max()

The fact that it returns false sounds wrong, but there’s the reason behind this output is very logical although not really immediate.

Math.min() returns the lowest-valued number passed into it, infinity if no arguments are given or NaN if any argument isn’t a number and can’t be converted into one

Math.max() returns the highest-valued number passed into it, -infinity if no arguments are given or NaN if any argument isn’t a number and can’t be converted into one

The two methods are an implementation of a for loop over the parameters as you can notice on the Chrome V8 implementation.

Math.max() starts with a search value of because any other number is going to be greater than -infinity .

Similarly, Math.min() starts with the search value of infinity.

Notice line 92 from V8 implementation.

HINT: Don’t pass an array as an argument of Math.min() or Math.max(), use the spread syntax.

Number.toFixed()

Sticking with numbers there’s something that I recently learned about Number.toFixed() that gave me a headache.

This method returns a string representing the given number using fixed-point notation, and the argument represents the number of digits to appear after the decimal point.

What is happening? Remember IEEE-754 from Give sense to nonsense series: weird JS explained?

Numbers in JS are regulated by IEEE-754 and due to the binary nature of their encoding, some decimal numbers cannot be represented with perfect precision, leading to unexpected results such as the above example or 0.1 + 0.2 different from 0.3.

HINT: Try to run the same code on Chrome, Firefox and IE11. Keep reading if you want to know why the results are different.

Array.prototype.sort()

If you worked with JS before, I’m pretty sure you got confused on this specific method. It doesn’t really output what you expect from a sorting algorithm.

How does sort work then? The ECMA specification explains this.

The default sort order is built upon converting elements into strings, then comparing their sequences of UTF-16 code units values.

If you want to sort an array of numbers then you’ll have to pass a comparator, in our specific case it’s going to look like:

You can find all the details here. Notice that is specified that “The time and space complexity of the sort cannot be guaranteed as it depends on the implementation”.

In short: JavaScript code is executed by a JavaScript engine (Chromium based browsers use V8), and each engine is implemented differently. That’s why Number.toFixed() has a different output on IE11 and that’s why time and space complexity vary depending on the implementation.

There would be a lot to write about this topic so I leave you some keywords to dig deeper into it: JavaScript engine, V8, Interpreter, JIT.

Final thoughts

More light has been shed on this language and his weirdness, and there’s even more to discover. I find it really interesting how much information and interesting topics you can find by studying what happens under the hood of a language.

--

--