JavaScript 中的 NaN 和 Infinity

JavaScript 中的 NaN 和 Infinity

这篇文章将介绍两个特殊值,它们通常是操作数字返回的结果:NaNInfinity

NaN

JavaScript 中的值 NaN 用来代表 "not a number"(不是一个数字)。它主要表示转换字符串发生错误:

Number('xyz'); // NaN

NaN 有一些特殊特性。它的名称是 "not a number"(不是一个数字),但是却不等于自身:

NaN !== NaN; // true

是的,它的类型是 "number"。

typeof NaN; // 'number

检测 NaN

NaN 是唯一不等于它自身的 JavaScript 值。没有相等的操作,你只能使用全局函数 isNaN() 来检测它。

isNaN(NaN); // true

isNaN() 的一个缺陷是:它首先强制转换参数为数字类型,因此对那些无法转化为数字的字符串使用时将返回 true

Number('xyz'); // NaN
isNaN('xyz'); // true

相同的结果,对许多对象类型使用 isNaN 也将返回 true

Number({}); // NaN
isNaN({}); // true

Number(['xzy']); // NaN
isNaN(['xzy']); // true

转换算法的详情查看文章。可以重写 valueOf 函数来控制转化为数字的结果:

const obj = {
  valueOf: function () {
    return NaN;
  },
};
Number(obj); // NaN
isNaN(obj); //true

一个建议办法是使用 NaN 是唯一不等于自身值的事实(x !== x):

function myIsNaN(x) {
  return x !== x;
}

ECMAScript 6 添加了一个新的版本 Number.isNaN(),规范的方法比上面的建议更好。它看起来像下面这样:

Number.isNaN = function (value) {
  return typeof value === 'number' && isNaN(value);
};

和全局函数 isNaN() 相比,Number.isNaN() 不会强制将参数转换成数字,只有在参数是真正的数字类型,且值为 NaN 的时候才会返回 true

Number.isNaN(NaN); // true
Number.isNaN('xyz'); // false
Number.isNaN({}); // false

Infinity

以 0 作为除数可以得到另一个特殊值(注意 0/0 返回 NaN):

3 / 0; // Infinity
-3 / 0; // -Infinity
0 / 0; // NaN

你不能对正/负 Infinity 彼此的运算(如下运算):

Infinity - Infinity; // NaN

也可以证实的是远大于无穷依然是无穷的:

Infinity + Infinity; // Infinity

5 * Infinity; // Infinity

引用

本文作者 Axel Rauschmayer,转载请注明来源链接:

原文链接:https://2ality.com/2012/02/nan-infinity.html

本文链接:https://tie.pub/2019/06/nan-and-infinity-in-javascript/