2

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
4
  • The two things are not equivalent. Do you expect pi.round(2) to mutate the number? That's impossible, since numbers are immutable. Commented Nov 20, 2014 at 8:55
  • What's wrong with pi.toFixed(2)? Commented Nov 20, 2014 at 8:57
  • Mutability: All I can do is nod and smile, pretending to know what that means. For what it is worth, Wikipedia says: "Custom classes are generally mutable. To simulate immutability in a class, one should set immutable properties to prototype of object." Commented Nov 20, 2014 at 9:27
  • toFixed: There is nothing wrong with it. To be honest, I didn't know about it. In any event, it makes a string and you have to convert it back into a number with valueOf(). Also, it does not perform backward rounding. Commented Nov 20, 2014 at 9:35

2 Answers 2

2

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:

Sign up to request clarification or add additional context in comments.

8 Comments

What is Number.prototype.contains?
The method 'contains' returns true or false. It is a way of checking that Number.prototype is not already being used.
I am not an advanced programmer, and just now starting to wrap my mind around prototyping. I was so proud of this one that I decided to show it off. If I am doing something wrong, please kick me and then explain why.
Number.prototype.contains is undefined in my Chrome.
Seems to be working as it should. In an 'if' statement, undefined resolves to 'false.' In this case, false will allow the block in the if statement to execute because of the use of the exclamation point.
|
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.