作者:Dmitri Pavlutin翻译:疯狂的技术宅
原文:https://dmitripavlutin.com/na...
未经允许严禁转载
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"
仅当 someNumber
是 NaN
时,someNumber !== someNumber
表达式才是 true
。因此,以上代码片段输出到控制台的结果是 "Is NaN"
。
JavaScript 通过内置函数来检测 NaN
:isNaN()
和 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/0
和 Infinity/Infinity
这样的的除法运算:
0 / 0; // => NaN
Infinity / Infinity; // => NaN
0
和 Infinity
的乘法运算:
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
是个好主意。
undefined
或 NaN
作为算术运算中的操作数通常会导致 NaN
。正确处理 undefined
(为缺少的属性提供默认值)是防止这种情况的好方法。
数学函数的不确定形式或无效参数也会导致 “Not A Number”。但是这些情况很少发生。
这是我的务实建议:出现了 NaN
?赶快检查是否存在 undefined
!
本文首发微信公众号:前端先锋
欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章
欢迎继续阅读本专栏其它高赞文章:
- 深入理解Shadow DOM v1
- 一步步教你用 WebVR 实现虚拟现实游戏
- 13个帮你提高开发效率的现代CSS框架
- 快速上手BootstrapVue
- JavaScript引擎是如何工作的?从调用栈到Promise你需要知道的一切
- WebSocket实战:在 Node 和 React 之间进行实时通信
- 关于 Git 的 20 个面试题
- 深入解析 Node.js 的 console.log
- Node.js 究竟是什么?
- 30分钟用Node.js构建一个API服务器
- Javascript的对象拷贝
- 程序员30岁前月薪达不到30K,该何去何从
- 14个最好的 JavaScript 数据可视化库
- 8 个给前端的顶级 VS Code 扩展插件
- Node.js 多线程完全指南
- 把HTML转成PDF的4个方案及实现