Number
Importantly, for your program to properly work, it must accurately handle numbers. ES6 adds some additional properties and functions to assist with common numeric operations.
Two additions to Number
are just references to the preexisting globals: Number.parseInt(..)
and Number.parseFloat(..)
.
Static Properties
ES6 adds some helpful numeric constants as static properties:
Number.EPSILON
- The minimum value between any two numbers:2^-52
(see Chapter 2 of the Types & Grammar title of this series regarding using this value as a tolerance for imprecision in floating-point arithmetic)Number.MAX_SAFE_INTEGER
- The highest integer that can “safely” be represented unambiguously in a JS number value:2^53 - 1
Number.MIN_SAFE_INTEGER
- The lowest integer that can “safely” be represented unambiguously in a JS number value:-(2^53 - 1)
or(-2)^53 + 1
.
Note: See Chapter 2 of the Types & Grammar title of this series for more information about “safe” integers.
Number.isNaN(..)
Static Function
The standard global isNaN(..)
utility has been broken since its inception, in that it returns true
for things that are not numbers, not just for the actual NaN
value, because it coerces the argument to a number type (which can falsely result in a NaN). ES6 adds a fixed utility Number.isNaN(..)
that works as it should:
var a = NaN, b = "NaN", c = 42;
isNaN( a ); // true
isNaN( b ); // true -- oops!
isNaN( c ); // false
Number.isNaN( a ); // true
Number.isNaN( b ); // false -- fixed!
Number.isNaN( c ); // false
Number.isFinite(..)
Static Function
There’s a temptation to look at a function name like isFinite(..)
and assume it’s simply “not infinite”. That’s not quite correct, though. There’s more nuance to this new ES6 utility. Consider:
var a = NaN, b = Infinity, c = 42;
Number.isFinite( a ); // false
Number.isFinite( b ); // false
Number.isFinite( c ); // true
The standard global isFinite(..)
coerces its argument, but Number.isFinite(..)
omits the coercive behavior:
var a = "42";
isFinite( a ); // true
Number.isFinite( a ); // false
You may still prefer the coercion, in which case using the global isFinite(..)
is a valid choice. Alternatively, and perhaps more sensibly, you can use Number.isFinite(+x)
, which explicitly coerces x
to a number before passing it in (see Chapter 4 of the Types & Grammar title of this series).
Integer-Related Static Functions
JavaScript number values are always floating point (IEEE-754). So the notion of determining if a number is an “integer” is not about checking its type, because JS makes no such distinction.
Instead, you need to check if there’s any non-zero decimal portion of the value. The easiest way to do that has commonly been:
x === Math.floor( x );
ES6 adds a Number.isInteger(..)
helper utility that potentially can determine this quality slightly more efficiently:
Number.isInteger( 4 ); // true
Number.isInteger( 4.2 ); // false
Note: In JavaScript, there’s no difference between 4
, 4.
, 4.0
, or 4.0000
. All of these would be considered an “integer”, and would thus yield true
from Number.isInteger(..)
.
In addition, Number.isInteger(..)
filters out some clearly not-integer values that x === Math.floor(x)
could potentially mix up:
Number.isInteger( NaN ); // false
Number.isInteger( Infinity ); // false
Working with “integers” is sometimes an important bit of information, as it can simplify certain kinds of algorithms. JS code by itself will not run faster just from filtering for only integers, but there are optimization techniques the engine can take (e.g., asm.js) when only integers are being used.
Because of Number.isInteger(..)
‘s handling of NaN
and Infinity
values, defining a isFloat(..)
utility would not be just as simple as !Number.isInteger(..)
. You’d need to do something like:
function isFloat(x) {
return Number.isFinite( x ) && !Number.isInteger( x );
}
isFloat( 4.2 ); // true
isFloat( 4 ); // false
isFloat( NaN ); // false
isFloat( Infinity ); // false
Note: It may seem strange, but Infinity should neither be considered an integer nor a float.
ES6 also defines a Number.isSafeInteger(..)
utility, which checks to make sure the value is both an integer and within the range of Number.MIN_SAFE_INTEGER
-Number.MAX_SAFE_INTEGER
(inclusive).
var x = Math.pow( 2, 53 ),
y = Math.pow( -2, 53 );
Number.isSafeInteger( x - 1 ); // true
Number.isSafeInteger( y + 1 ); // true
Number.isSafeInteger( x ); // false
Number.isSafeInteger( y ); // false