专栏首页京程一灯JavaScript 中的 NaN

JavaScript 中的 NaN

每日前端夜话第268篇

翻译:疯狂的技术宅

作者:Dmitri Pavlutin

来源:dmitripavlutin

正文共:1315 字

预计阅读时间:6分钟

JavaScript 中的数字类型包含整数和浮点数:

const integer = 4;
const float = 1.5;

typeof integer; // => 'number'
typeof float;   // => 'number'

另外还有 2 个特殊的数字值:Infinity(比其他任何数字都大的数字)和 NaN(表示“Not A Number”概念):

const infinite = Infinity;
const faulty = NaN;

typeof infinite; // => 'number'
typeof faulty;   // => 'number'

虽然直接使用 NaN 的情况很少见,但在对数字进行无效的操作后却会令人惊讶地出现。

让我们仔细看看 NaN 特殊值:如何检查变量是否具有 NaN,并了解怎样创建“Not A Number”值。

NaN number

JavaScript 中的数字类型是所有数字值的集合,包括 “Not A Number”,正无穷和负无穷。

可以使用特殊表达式 NaN 、全局对象或 Number 函数的属性来访问“Not A Number”:

typeof NaN;        // => 'number'
typeof window.NaN; // => 'number'
typeof Number.NaN; // => 'number'

尽管具有数字类型,但“Not A Number”是不代表实数的值。NaN 可用于表示错误的数字运算。

例如,将数字与 undefined 相乘不是有效操作,因此结果为 NaN

1 * undefined;     // => NaN

同样尝试解析无效的数字字符串(如 'Joker')也会导致 NaN

parseInt('Joker', 10); // => NaN

检查 NaN 是否相等

NaN有趣的特性是,即使使用 NaN本 身,它也不等于任何值:

NaN === NaN; // => false

此行为对于检测变量是否为 NaN 非常有用:

const someNumber = NaN;

if (someNumber !== someNumber) {  console.log('Is NaN');
} else {
  console.log('Is Not NaN');
}

// logs "Is NaN"

仅当 someNumberNaN 时,someNumber !== someNumber 表达式才是 true。因此,以上代码片段输出到控制台的结果是 "Is NaN"

JavaScript 通过内置函数来检测 NaNisNaN()Number.isNaN()

isNaN(NaN); // => true
isNaN(1);   // => false

Number.isNaN(NaN); // => true
Number.isNaN(1);   // => false

这些函数之间的区别在于,Number.isNaN() 不会将其参数转换为数字:

isNaN('Joker12');        // => true
Number.isNaN('Joker12'); // => false

isNaN('Joker12') 将参数 'Joker12' 转换为数字,即 NaN。因此该函数返回 true

另一方面,Number.isNaN('Joker12') 会检查参数是否为 NaN 而不进行转换。该函数返回 false ,因为'Joker12' 不等于 NaN

导致 NaN 的运算

1 解析数字

在 JavaScript 中,你可以将字符串形式的数字转换为数字。

例如你可以轻松地将字符串 '1.5' 转换为浮点数 1.5

const numberString = '1.5';
const number = parseFloat(numberString);

number; // => 1.5

当字符串不能被转换为数字时,解析函数返回 NaN :表示解析失败。这里有些例子:

parseFloat('Joker12.5'); // => NaN
parseInt('Joker12', 10); // => NaN
Number('Joker12');       // => NaN

解析数字时,最好先确认解析结果是否为 NaN

let inputToParse = 'Invalid10';
let number;

number = parseInt(inputToParse, 10);
if (isNaN(number)) {  number = 0;
}

number; // => 0

解析 inputToParse 失败,因此 parseInt(inputToParse, 10)返回 NaN。条件 if (isNaN(number))true,并且将 number 赋值为 0

2 undefined 作为操作数

undefined 用作加法、乘法等算术运算中的操作数会生成 NaN

例如:

function getFontSize(style) {
  return style.fontSize;
}

const fontSize = getFontSize({ size: 16 }) * 2;
const doubledFontSize = fontSize * 2;

doubledFontSize; // => NaN

getFontSize() 是从样式对象访问 fontSize 属性的函数。调用 getFontSize({ size: 16 }) 时,结果是undefined(在 { size: 16 } 对象中不存在 fontSize 属性)。

fontSize * 2 被评估为 undefined * 2,结果为 NaN

当把缺少的属性或返回 undefined 的函数用作算术运算中的值时,将生成 “Not A Number”。

防止 NaN 的好方法是确保 undefined 不会进行算术运算,需要随时检查。

3 NaN 作为操作数

当算数运算的操作数为 NaN 时,也会生成NaN 值:

1 + NaN; // => NaN
2 * NaN; // => NaN

NaN 遍及算术运算:

let invalidNumber = 1 * undefined;
let result = 1;
result += invalidNumber; // appendresult *= 2;             // duplicate
result++;                // increment

result; // => NaN

在将 invalidNumber 值(具有 'NaN')附加到 result之后,会破坏对 result 变量的操作。

4 Indeterminate 形式

当算术运算采用不确定形式时,将会产生 NaN 值。

0/0Infinity/Infinity 这样的的除法运算:

0 / 0;               // => NaN
Infinity / Infinity; // => NaN

0Infinity 的乘法运算:

0 * Infinity; // => NaN

带有不同符号的 Infinity 的加法:

-Infinity + Infinity; // => NaN

5 无效的数学函数参数

负数的平方根:

Math.pow(-2, 0.5); // => NaN
(-2) ** 0.5;       // => NaN

或负数的对数:

Math.log2(-2); // => NaN

总结

JavaScript 中用 NaN 表示的的“Not A Number”概念对于表示错误的数字运算很有用。

即使是 NaN 本身也不等于任何值。检查变量是否包含 NaN 的建议方法是使用 Number.isNaN(value)

将字符串形式的数字转换为数字类型失败时,可能会导致显示“Not A Number”。检查 parseInt()parseFloat()Number() 是否返回了 NaN 是个好主意。

undefinedNaN 作为算术运算中的操作数通常会导致 NaN。正确处理 undefined(为缺少的属性提供默认值)是防止这种情况的好方法。

数学函数的不确定形式或无效参数也会导致 “Not A Number”。但是这些情况很少发生。 这是我的务实建议:出现了 NaN?赶快检查是否存在 undefined

原文:https://dmitripavlutin.com/nan-in-javascript/

本文分享自微信公众号 - 前端先锋(jingchengyideng),作者:疯狂的技术宅

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-01-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JavaScript真假值知多少

    当用`==`比较的时候,似乎不同的值和true都是相等的。因为在比较前JavaScript会把每个值转换成字符串形式:

    疯狂的技术宅
  • 奇怪的 Javascript

    我的意思是,对于刚开始使用这种语言和他语言(例如 C++ 或 C#)的开发人员来说,javascript 可能会很奇怪。

    疯狂的技术宅
  • 炫技!JavaScript 的花式玩法

    JavaScript 是一个伟大的语言。它有简单的语法,完善的生态系统,更重要的,有一个庞大的社区。

    疯狂的技术宅
  • pandas中ix的使用详细讲解

    在上一篇博客中,我们已经仔细讲解了iloc和loc,只是简单了提到了ix。这是因为相比于前2者,ix更复杂,也更让人迷惑。

    砸漏
  • AkShare-期货数据-仓单日报

    目标地址: http://www.czce.com.cn/cn/jysj/cdrb/H770310index_1.htm

    AkShare
  • AkShare-能源数据-碳排放-国际行情

    目标地址: http://www.cerx.cn/dailynewsOuter/index.htm

    AkShare
  • 小心double的比较

    对于double的比较,存在一些可能的坑,大家应该都清楚。比如容易注意的是double==double的精度问题。但是比较少注意的是double.NaN的比较

    黄腾霄
  • Under the Hood: NaN of JS

    如果你还不确定这两题的答案的话,请仔细阅读本文。 这两题的答案不会直接解释,请从文章中寻找答案。

    有赞coder
  • 【机器学习实战】第13章 利用 PCA 来简化数据

    第13章 利用 PCA 来简化数据 ? 降维技术 场景 我们正通过电视观看体育比赛,在电视的显示器上有一个球。 显示器大概包含了100万像素点,而球则可能...

    片刻
  • javascript 红皮高程(7)

    javascript的数值表示,真是。。 这还有个NaN,非数值(Not a Number),就是不是数字。然后已是书里写着,是一个特殊的数值。 这让小学文化的...

    web前端教室

扫码关注云+社区

领取腾讯云代金券