Add a rounding method to Number.prototype in JavaScript

3.6k views Asked by At

How can I simplify rounding in JavaScript? I wish that I could do it in a more elegantly in an object-oriented manner. The method toFixed works well, but does not have backward rounding and it also returns a string and not a number.

pi.toFixed(2).valueOf();
// 3.14

As it is, rounding is a bit of a tangle because I have to use:

pi = Math.round(pi * 100) / 100;
// 3.14

It would be much nicer instead just to stick a method to the end of a variable, such as:

pi.round(2);
// 3.1r
2

There are 2 answers

8
Heyzeuss On

Extend Number.prototype. Numbers in Javascript are a data type that is associated with the built-in object "Number." Add the following polyfill block:

if (!Number.prototype.round) {
    Number.prototype.round = function (decimals) {
        if (typeof decimals === 'undefined') {
            decimals = 0;
        }
        return Math.round(
            this * Math.pow(10, decimals)
        ) / Math.pow(10, decimals);
    };
}

Anywhere after this, you can round numbers by sticking .round() to the end of them. It has one optional parameter that determines the number of decimals. For example:

pi.round(2);

You can also use backward rounding with negative numbers such as:

x = 54321;
x.round(-4);
// 50000

Fiddle: http://jsfiddle.net/g2n2fbmq/

Related:

0
user3654410 On

First off: Don't do it

Extending builtin prototypes is generally frowned upon as new standards may break your code. Libraries that extended builtin prototypes have caused trouble in the past.

However if you really want to and accept the risk, it should be relatively safe if you add a prefix that is unlikely to be adopted by any standard.

if (!Number.prototype.$round) {
  Object.defineProperty(Number.prototype, '$round', {
    value(precision) {
      return +this.toFixed(precision)
    },
  })
}

(123.456789).$round(2) // 123.45

By prefixing the property with $, your code will continue to work if Number#round() is standardized.

I use Object.defineProperty instead of = as it makes the property non-enumerable by default. Meaning it won't show up in for..in-loops.