You are probably aware that ECMAScript has something called JavaScript Infinity, which is a numeric value that you can apply to any variable, the same way you can apply other numbers as values for variables.
Infinity
of course is not the same as other numbers, so I thought I’d summarize, with examples, many of the quirks and useful facts around JavaScript Infinity and how it works.
What is Infinity
?
As mentioned, Infinity
is a numeric value. Technically, Infinity
is classified as a property of the Window
object, similar to how variables in the global scope become properties of Window
:
console.log(window.Infinity); // Infinity
console.log(window.Infinity > 100); // true
console.log(window.Infinity < 100); // false
Despite this, Infinity
is not writable, enumerable, or configurable. So you can’t use something like for...of
with Infinity
as the object:
// This won't work!
// Uncaught TypeError: Infinity is not iterable
for (let i of Infinity) {
console.log(i);
}
Which is not surprising because you can’t do that with any number; you can only do it with an iterable object. But you can use Infinity
as the ceiling of a customary for
loop:
// Don't do this!
for (let i=0; i<Infinity; i++) {
// Infinite loop
}
Naturally, this creates an infinite loop and will either crash your browser or your browser will warn you that your script has an infinite loop and will attempt to escape it.
When is Infinity
Returned?
A calculation will return Infinity
if the value returned is too high. That is, if it passes a certain threshold. You can find out more or less what that threshold is by typing numbers into the browser’s console until you get a return that equals Infinity
, as shown in the following video.
In this case, I’ve typed a nine more than 300 times. It actually doesn’t seem to matter what digit I type, as long as it’s not all zeroes; once I hit 309 digits, the return will be Infinity
.
A number like the one above can also be represented in scientific notation using the format 1e309
. So, for example, if I were to set two variables to the values 1e308
and 1e309
, respectively, you’ll notice how they differ when I try to log them to the console:
let bigNumber = 1e308,
biggerNumber = 1e309;
console.log(bigNumber); // 1e+308
console.log(biggerNumber); // Infinity
Again, this just demonstrates the approximate threshold where Infinity
starts to be returned. To be even more precise, according to the spec, Infinity
represents all values greater than 1.7976931348623157e+308
:
let largeNumber = 1.7976931348623157e+308,
largerNumber = 1.7976931348623157e+309;
console.log(largeNumber); // 1.7976931348623157e+308
console.log(largerNumber); // Infinity
Infinity
will also be returned when a number is divided by zero:
console.log(46 / 0); // Infinity
This is not the same as what happens when you attempt this on a calculator, which usually will say something like “Cannot divide by zero” or a similar error message.
Another way to return Infinity
is via a property of JavaScript’s Number
object, as shown in the following code:
console.log(Number.POSITIVE_INFINITY); // Infinity
This constant isn’t very useful, however, because it can only be used in the form shown above, and can’t be used on a Number
object you create yourself (although I’m not sure why you would want to do that anyhow).
Checking for Infinity
Based on the constants mentioned in the previous section, you can check for Infinity
using something like this:
function checkForInfinity (value) {
return value === Number.POSITIVE_INFINITY;
}
console.log(checkForInfinity(Infinity)); // true
console.log(checkForInfinity(789)); // false
console.log(checkForInfinity(1.7976931348623157e+308)); // false
console.log(checkForInfinity(1.7976931348623157e+309)); // true
Here I’m simply comparing the passed in value to the Number.POSITIVE_INFINITY
constant which always returns Infinity
.
On a related point, JavaScript has an isFinite()
method that can be used to test if a value is finite (that is, it’s not equal to Infinity
). This might be necessary if there are some calculations taking place where you suspect a dynamic value might get too large. Some basic logs demonstrate how isFinite()
can be used:
console.log(isFinite(45)); // true
console.log(isFinite(-45)); // true
console.log(isFinite(Infinity)); // false
console.log(isFinite(1.7976931348623157e+308)); // true
console.log(isFinite(1.7976931348623157e+309)); // false
But care needs to be taken when using isFinite()
, because it will coerce non-number values to numbers:
console.log(isFinite('45')); // true
console.log(isFinite('-75')); // true
So keep this in mind when using isFinite()
. This method will return false
for any non-number (e.g. a string that doesn’t coerce). So you may only want to use it if you know the value being checked could not possibly be anything but a finite or infinite number (i.e. it’s not a string or other type).
Infinity
Can Be Positive or Negative
Although Infinity
is commonly viewed as a ‘big number’, it can also take on the role of the smallest possible number when represented as a negative. Below are some console tests to demonstrate.
First some standard greater-than and less-than tests:
console.log(Infinity > 100); // true
console.log(Infinity < 100); // false
console.log(-Infinity > 100); // false
console.log(-Infinity < -100); // true
Now I’ll compare positive Infinity
to the highest possible non-Infinity
value and negative Infinity
to the lowest possible negative value that’s not negative Infinity
:
console.log(Infinity > 1.7976931348623157e+308); // true
console.log(-Infinity < -1.7976931348623157e+308); // true
And here I’ll confirm where the Infinity
threshold begins in both positive and negative:
console.log(1.7976931348623157e+309); // Infinity
console.log(-1.7976931348623157e+309); // -Infinity
As you might guess, if you divide a negative number by zero, the return will be -Infinity
:
console.log(-46 / 0); // -Infinity
You can also return -Infinity
using the following property of the Number
object, which is similar to the positive infinity property mentioned earlier:
console.log(Number.NEGATIVE_INFINITY); // -Infinity
Interestingly, Math.max()
(which returns the largest of the passed in values) will return -Infinity
if no values are passed in, and Math.min()
(which returns the lowest of the passed in values) will return Infinity
if no values are passed in.
console.log(Math.max()); // -Infinity
console.log(Math.min()); // Infinity
Infinity as a Default Value
In his new book JavaScript for impatient programmers, Axel Rauschmayer has an interesting use case for Infinity
as a default value. Since Infinity
is larger than all numbers, it can be useful in a function that checks for the minimum number in an array:
function findMinimum(numbers) {
let min = Infinity;
for (const n of numbers) {
if (n < min) min = n;
}
return min;
}
console.log(findMinimum([20, 6, 90])); // 6
This works nicely because Infinity
is greater than all numbers so unless all the numbers in the array cross the Infinity
threshold, the result won’t have any problems.
Beware of Infinity when Converting to JSON
When dealing with JSON data, if you’re using JSON.stringify()
to convert a JavaScript object to a valid JSON string, you should be aware how Infinity
values are treated. Notice the following example:
let myJSON = {
value1: 6,
value2: 'Example Text',
value3: Infinity,
value4: -Infinity,
value5: 1.7976931348623157e+309
};
console.log(JSON.stringify(myJSON, null, 2));
/* Result:
"{
'value1': 6,
'value2': 'Example Text',
'value3': null,
'value4': null,
'value5': null
}"
*/
Notice the original data in the JavaScript object, prior to being stringified, includes three different infinite values. When the data is actually stringified, however, those values are all converted to null
. This would also happen if one of the values was initially NaN
.
Conclusion
So that’s just about everything I’ve learned about the JavaScript Infinity value. I hope some of this was interesting to you, even if you’ve been writing JavaScript for some time.
Did I miss anything or misstate something about the quirks of JavaScript Infinity? Feel free to let me know in the comments or on Twitter.
If the values are infinity, why does the value comparisons(
==
) fail betweenNumber.POSITIVE_INFINITY
,Number.MAX_VALUE
andMath.max()
?Good question!
First,
Math.max()
with no arguments returns negative Infinity andMath.min()
with no arguments returns positive Infinity. So you’d have to useMath.min()
if comparing to the two you mentioned.And my guess is that
Number.POSITIVE_INFINITY
is not equal toNumber.MAX_VALUE
because they’re different properties of the Number object, so technically they’re not the same thing. And the same would apply toMath.min()
.EDIT: I made a mistake in the article.
Number.MAX_VALUE
does not returnInfinity
, so none of the three that you mentioned are actually equal to each other. My bad!in my browser
console.log(Number.MAX_VALUE) // 1.7976931348623157e+308
You’re right! Not sure why I said it returns Infinity. I’ve corrected the article, thank you!
also the Number.MIN_VALUE, it is 5e-324 not -Infinity
Yes, thank you. I think when I was writing this, I got mixed up between Math.max()/min() and Number.MAX_VALUE/MINVALUE, because I didn’t seem to make any demos for the Number ones. Thanks again for the fixes.
Thanks a lot! Great.