The Weird World of Infinity in JavaScript

You are probably aware that ECMAScript has something called 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.

Dividing by zero on a calculator

Another way to return Infinity is via two properties of JavaScript’s Number object, as shown in the following code:

console.log(Number.POSITIVE_INFINITY); // Infinity
console.log(Number.MAX_VALUE); // Infinity

These constants aren’t very useful, however, because they 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) {
  // You can also use Number.MAX_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. I could also do the same using Number.MAX_VALUE.

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 two properties of the Number object, which are similar to the properties mentioned earlier:

console.log(Number.NEGATIVE_INFINITY); // -Infinity
console.log(Number.MIN_VALUE); // -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 ECMAScript’s 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 Infinity in JavaScript? Feel free to let me know in the comments or on Twitter.

2 Responses

  1. Chechs says:

    If the values are infinity, why does the value comparisons(==) fail between Number.POSITIVE_INFINITY, Number.MAX_VALUE and Math.max()?

    • Good question!

      First, Math.max() with no arguments returns negative Infinity and Math.min() with no arguments returns positive Infinity. So you’d have to use Math.min() if comparing to the two you mentioned.

      And my guess is that Number.POSITIVE_INFINITY is not equal to Number.MAX_VALUE because they’re different properties of the Number object, so technically they’re not the same thing. And the same would apply to Math.min().

      I believe this article explains the concept that’s at play here.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).