Every few weeks, I catch code where the programmer (sometimes me) is bending over backwards to try to solve a problem that ES6 (or sometimes even older versions of JavaScript) already solves. In fact, the interviewers who interviewed me for my current job, ask interviewees for a method on a built-in datatype that’s been in JavaScript for a long time. No one ever uses the built-in method, we all try to write it from scratch. That experience reminds me to always learn and refresh on the basics of your skill set. The Number type is new-ish, but is widely under utilized for some very common functionality. (It’s not the subject of the interview.)

The ES6 Number datatype. Keep in mind the Number and it’s methods are not available in Internet Explorer and mobile browsers (12% or so of users in December 2016) without shimming or transpiling. If you’re not shimming or transpiling for a professional app, you probably should because of browser compatibility and cross-browser inconsistencies; though there are exceptions depending on your audience and performance requirements of course.

The Number Object goes well with HTML5’s number. There’s not a lot of use of this input because it’s ugly and confusing, but it’s something to keep in mind.

Otherwise, if you’re not sure the value is a number or not, you can use the Number constructor to explicitly and predictably cast it as an instance of Number.

### The Constructor of the Number Object

In this example, we convert data from an unpredictable source like a text input or AJAX response.

1 |
numberObject = new Number(data); |

These result of using this will be mathematically consistent, but the convenience of using the Number datatype is most valuable to prevent the developer from having to think about math. So here’s some common uses:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
new Number(1) // Number {[[PrimitiveValue]]: 1} new Number(1.1) // Number {[[PrimitiveValue]]: 1.1} new Number('11') // Number {[[PrimitiveValue]]: 11} new Number('11.1') // Number {[[PrimitiveValue]]: 11.1} new Number(true) // Number {[[PrimitiveValue]]: 1} new Number(false) // Number {[[PrimitiveValue]]: 0} new Number(null) // Number {[[PrimitiveValue]]: 0} new Number('a') // Number {[[PrimitiveValue]]: NaN} new Number('11,1') // Number {[[PrimitiveValue]]: NaN} new Number(undefined) // Number {[[PrimitiveValue]]: NaN} new Number(void 0) // Number {[[PrimitiveValue]]: NaN} // notice these three throw developers off from time to time. new Number(true) // Number {[[PrimitiveValue]]: 1} new Number(false) // Number {[[PrimitiveValue]]: 0} new Number(null) // Number {[[PrimitiveValue]]: 0} // but thankfully, there's only one level of implicit conversion. new Number('true') // Number {[[PrimitiveValue]]: NaN} new Number('false') // Number {[[PrimitiveValue]]: NaN} new Number('null') // Number {[[PrimitiveValue]]: NaN} |

This is great, it’s predictable: you’re going to get a Number Object and it’s either going to have a value of a number or “not a number.”

### Numbers you can use

When you want to see if a value passed as an argument to a function is a usable number? Before ES6 you had the global isFinite function. You can still use it, but it’s hard to remember all of the built in globals, they’re more likely to get written over, but perfectly acceptable. I prefer using the new ones built on the Number object. I like code to be intentional and explicit. Further, there’s potential for JavaScript runtimes to lack the window methods; for instance, NodeJS doesn’t have the window object, if you’re using window[method] notation, your code wouldn’t be reusable unless you account for global[method]. Native run times may eliminate global methods altogether, since they’re not as chained to the Browser API.

1 2 3 4 5 6 |
// Check to see if a value is safe to use. if(Number.isFinite(value)) ... // is the same as if(isFinite(value)) ... |

Here’s some examples of what you get using Number.isFinite(value):

1 2 3 4 5 6 7 8 9 10 |
Number.isFinite(1) // true Number.isFinite(1.1) // true Number.isFinite(NaN) // false Number.isFinite("a") // false Number.isFinite(Infinity) // false Number.isFinite(-Infinity) // false Number.isFinite(undefined) // false Number.isFinite(1/0) // false Number.isFinite(null) // false |

The first thing you can do is use the Number constructor to explicitly recast strings consisting only of a number to a Number type.

1 2 3 |
// if you want to accept strings consisting only of a number, // you can get that by using the Number constructor like this. value = new Number(value); |

So you can do something like this:

1 2 3 4 5 6 7 8 |
function(arg){ // if you want to accept strings consisting only of a number... numberObject = new Number(arg); if(!Number.isFinite(numberObject)){ // throw, reject, return, etc. } // the rest of your code. } |

### Using the number

If you want to work with that number like you would a number literal, you can get the value back by using the “valueOf” method.

1 |
value = numberObject.valueOf(); |

You can use the “value” just as you would any number literal or trusted variable. Otherwise, you can use the “numberObject” (the instance of Number holding our value) and all of the methods that live on the instance (covered in future posts).

### Other Global Number methods

Number also includes methods for checking a number to see if it is an integer and safe integer.

1 2 3 4 5 6 7 8 9 10 11 |
Number.isInteger(100) //true Number.isInteger(-100) //true Number.isInteger(.1) // false Number.isInteger(1000000000000000000000) //may be true, may not. I got true. Number.isSafeInteger(100) // true Number.isSafeInteger(1000000000000000000000) // false Number.isSafeInteger(1.1) // false Number.isInteger(Infinity) // false Number.isInteger(-Infinity) // false |

Number also has methods for the globals isNaN, parseInt, and parseFloat.

### Number’s you can’t lose: Constants

My audience is unlikely to use these Constant properties, but here they are:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Number.MAX_SAFE_INTEGER // Largest integer guaranteed by all JavaScript runtimes. Number.MAX_VALUE // Largest number guaranteed by all JavaScript runtimes. Number.MIN_SAFE_INTEGER // Smallest integer guaranteed by all JavaScript runtimes. Number.MIN_VALUE // Smallest number guaranteed by all JavaScript runtimes. // Your browser might handle a larger or smaller number // just fine, but if you're in a different browser or you //start doing math with the numbers, JavaScript can't // guarantee precision. Number.EPSILON // Skip this comment: // We're not going to use this, it relates to floating point // math and how you can get really close to zero. Like when // you see weird results like .2-.3+.1=2.7755575615628914e-17 // (which happens not to equal Number.EPSILON, but my browser // will tell you it is equal. |

Next time, we’ll look at some of the instance methods on the global Number object.