DEV Community

Discussion on: 9 Extremely Powerful JavaScript Hacks

Collapse
stephenmirving profile image
Stephen Irving • Edited on

I wanted to point out that #9 (using length to empty an array) is particularly useful if you are using ES6+ syntax and declaring your arrays with const instead of var. This keeps you from having to declare your array with let just to empty it.

I also wanted to share that according to tests I ran using several benchmarking tools, it is slightly faster on some browsers to convert a string to a number by multiplying it by 1 then by using the + operator as you do in #4:

const stringNum = "256.3"
const number = stringNum * 1;
console.log(number); // Logs 256.3

The difference is pretty negligible though. The fastest three methods were all very close in speed. Your method, the above method of multiplying by 1, and in a close third is using the Number constructor:

const number = Number(stringNum);

Here are another couple of quick things I've picked up.

A more performant and shorter replacement for Math.trunc(num) and parseInt(num), as well as working as a replacement for Math.floor(num) if you know the number won't be negative, using bitwise operator. This works on numbers stored as strings as well as regular numbers:

const num = 568.328;
const strNum = "243.782";

const truncatedNum1 = num|0;
const truncatedNum2 = strNum|0;

console.log(truncatedNum1); // Logs 568
console.log(truncatedNum2); // Logs 243

A more performant, albeit limited, way to fix a number to a single decimal place rather than use the incredibly slow num.toFixed(1):

const fixToOne = num =>
  (num = Math.round(num * 10) / 10) + (num === (num|0) ? '.0' : '');

fixToOne(2.3892); // Returns "2.4"

You can change the function by wrapping the returned value in parens and multiply by 1 at the end if you need a number returned rather than a string, but toFixed() returns a string so that's what I decided to return too.

A more performant but limited way to fix a number to two decimal places rather than use the incredibly slow num.toFixed(2):

const fixToTwo = num => 
  (num = (Math.round(num * 100) / 100) +
  (num === (num|0) ? '.0' : 0)) + (num === (num|0) ? '.0' : '') +
  (num * 10 === ((num * 10)|0) ? '0' : '');

fixToTwo(2.3892); // Returns "2.39"

You can see the benchmarks on these custom functions versus the native toFixed() and witness how drastic the speed difference is here: jsperf.com/decimal-rounding-tofixe...

Collapse
razgandeanu profile image
Klaus Author

That's really interesting.
Thank you for sharing that information with us.
I appreciate it.

Collapse
stephenmirving profile image
Stephen Irving

No problem. I added it to above post in an edit after your reply, but in case you didn't see it and are interested, you can check out my benchmarks for the custom toFixed functions here:

jsperf.com/decimal-rounding-tofixe...

It is DRASTICALLY faster as toFixed is painfully slow. Usually this wouldn't matter, but I had a usecase where I had an animation function that was getting called dozens of times a second and there were 3 places in it that required fixing a value to a set number of decimal places. Animation was noticeably smoother when I replaced toFixed with my custom functions.

Collapse
gustvandewal profile image
Gust van de Wal

"You can change the function by wrapping the returned value in parens and multiply by 1 at the end if you need a number returned rather than a string"

But the function already has a part that freshly generates the raw rounded number: Math.round(num * 10) / 10. Just leaving that part will do; no need to generate a number -> cast to string -> cast to number

Collapse
mburszley profile image
Maximilian Burszley

bitwise operator

Do note that limits the returns to 32-bit and will lose data on larger decimals/integers.