整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

JavaScript中的NaN是什么?

JavaScript中,NaN代表"Not a Number",即非数字,是一个特殊的值,用于表示某些数学运算的结果未定义或不可表示。NaN是JavaScript中唯一一个与自身不相等的值,也就是说,`NaN === NaN`的结果为`false`。

NaN常常在尝试进行无法返回有效数字值的数学运算时出现。例如,当你尝试将一个字符串(除非它是一个可以解析为数字的字符串)转换为数字时,JavaScript会返回NaN。

let num = Number("hello");

console.log(num); // 输出 NaN

此外,除以0或者某些无法得出有效结果的数学函数(例如Math.sqrt(-1))也会返回NaN。

let num1 = 10 / 0;

let num2 = Math.sqrt(-1);

console.log(num1); // 输出 NaN

console.log(num2); // 输出 NaN`

虽然NaN表示一个非数字的值,但它本身其实是一个数字类型。可以使用`typeof`运算符来验证这一点:

let num = Number("hello");

console.log(typeof num); // 输出 "number"`

由于NaN的特殊性,我们不能直接使用等于(==)或全等(===)运算符来检查一个值是否为NaN。我们需要使用`isNaN()`函数来进行这个检查。但需要注意的是,`isNaN()`函数不仅会在值为NaN时返回`true`,还会在值为`undefined`时返回`true`。为了避免这种情况,我们可以使用`Number.isNaN()`函数,这个函数只有在参数是NaN时才会返回`true`。

let num1 = NaN;

let num2 = undefined;

console.log(isNaN(num1)); // 输出 true

console.log(isNaN(num2)); // 输出 true

console.log(Number.isNaN(num1)); // 输出 true

console.log(Number.isNaN(num2)); // 输出 false`

虽然NaN在某些情况下可能会让人感到困惑,但理解它的行为和如何在JavaScript中处理它是非常重要的。这可以帮助我们避免一些常见的编程错误,并更准确地控制我们的代码的行为。

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

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。

2undefined 作为操作数

把 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 不会进行算术运算,需要随时检查。

3NaN 作为操作数

当算数运算的操作数为 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!


作者:前端先锋
链接:https://juejin.cn/post/6844904047787376654
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在javascript中最有趣的数据莫过于NaN,对于大部分小猿们刚接触到这个概念的时候表情应该是这样的。本篇博客就来给各位客官介绍下NaN的知识点。

NaN的介绍

  • 在很多语言中都有NaN,比如C语言中nan和R语言中NAN以及javascript中的NaN,虽然每一门语言的拼写不一样,但是他们表示的含义几乎一致,NaN全称 not a number,表示的是一个非数字。
  • 在javascript中NaN代表的含义也是代表一个非数字,非数字的情况就太多:一段字符串,一个函数,甚至是数组和对象,那么这个NaN到底属于哪种数据类型呢?答案是NaN属于数值类型(Number)。
  • 纳尼,不是刚刚说过not a number,怎么又说它属于Number类型呢?

  • 客官莫慌,容本猿给你狡辩狡辩,这里面我们要先搞清楚一个概念,就是数据类型Number
  • Number(数值)是javascript中的一种数据类型,其中包含了各种数值情况:十进制、八进制、十六进制等各种进制,而我们正常的数字属于Number(数值)类型的一个子集,不正常的数字也是Number的一个子集,而NaN就是不正常数字的一种情况。
  • 请允许我用抽象派的画技来给客官展示



  • 我猜你已经差不多懂我的意思,总结起来就是一句话(中文的博大精深)
    • NaN是数值类型,但不是一个正常的数字,是一个非数字,仅仅一字之差。



NaN的产生

这个NaN到底如何产生的,结合本猿开发和查找资料总结以下两种情况

  • 在其他类型转换成数值类型时候(包含手动转换和自动转换)
      • 手动转换
 var num = Number('千峰')     
 console.log(num) // NaN
      • 自动转换
 var num = '千峰' * '大前端'     
 console.log(num) // NaN
      • 我们以一种情景对话的方式模拟情景

  • 在数值某些计算的时候
var x = Math.sqrt(-1)         
console.log(x)
      • Math.sqrt()方法是用来求平方根,但是只有一个正数才有平方根,负数是没有平方根的,针对于这样的计算到底给什么结果呢,js给出的结果就是NaN

NaN有趣的灵魂

  • 既然介绍完了NaN,那我们聊点有趣的,本猿给客官们总结了两点。
  1. NaN和任何数的计算 js
console.log(NaN+1) // NaN     
console.log(NaN*1) // NaN     
console.log(NaN/1) // NaN     
// ...
  • 经过本猿的观测,任何一个数和NaN的计算,结果都是NaN,各位客官们是不是感受到了快乐


  • NaN和任何数的比较

本猿针对于几种可能会混淆情况比较,发现结果都是false

console.log(NaN === 0) // false     
console.log(NaN === '') // false     
console.log(NaN === undefined) // false     
console.log(NaN === null) // false

难道是我用了全等,抱着试一试态度我又换成了==,结果也是false

console.log(NaN == 0) // false     
console.log(NaN == '') // false     
console.log(NaN == undefined) // false     
console.log(NaN == null) // false

经过我反复测试,得出的结果是NaN和任何数据比较的结果都是false,但是感觉好像还有什么遗漏


名侦探柯南上身的我发现还有一种情况没有考虑

console.log(NaN === NaN) // false     
console.log(NaN == NaN) // false 


  • 彻底破防了,这个NaN竟然和自己都不相等,那么如何去判断某个数据是不是NaN呢?
  • 正当我准备给ECMASCript提出草案的时候,突然想到了之前NaN的黄金搭档 isNaN() 方法,这个方法就是天生为了检测NaN准备的
console.log(isNaN(NaN)) // true 

总结

  • 本篇主要给大家介绍下NaN的概念,希望各位猿猿们在日后开发中能够正确使用NaN和成功避免NaN留下的坑点,如有不足欢迎指正,谢谢。