前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库JavaScript NaN 判断
JavaScript值与类型

为什么 NaN 不等于自身?怎么可靠地判断一个值是不是 NaN?

NaN 表示一次数值运算没有得到有效结果。IEEE 754 规定 NaN 不等于任何值,包括自己,所以 NaN === NaN 是 false。判断一个值是不是 NaN,用 Number.isNaN(),它不做类型转换,只在参数真的是 NaN 时返回 true。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#值与类型
先看核心答案读代码示例
理解线索

`NaN` 的三个特殊行为

  1. 不等于自身这是 IEEE 754 标准的要求,== 和 === 都返回 false
  2. 传播性任何包含 NaN 的运算结果还是 NaN
  3. 检测方式Number.isNaN 最可靠,Object.is 和 includes 也能识别

typeof NaN 返回 "number",类型没错但值不可用。收到 NaN 说明上游某步运算出了问题,不要简单地替换成 0。

核心回答

先记住这个答案

NaN 是 Number 类型里的一个特殊值,表示某次数值运算没有产生有意义的结果。比如 0 / 0、parseInt("abc")、Math.sqrt(-1) 都会返回 NaN。IEEE 754 标准规定 NaN 不等于任何值,包括它自己,所以 NaN === NaN 和 NaN == NaN 都是 false。可靠的检测方式是 Number.isNaN(),它只在参数确实是 NaN 时返回 true,不做隐式类型转换。

  • NaN === NaN 为 false
  • Number.isNaN() 不做类型转换,最可靠
  • 全局 isNaN() 会先转数字,容易误判
  • includes 能找到 NaN

Number.isNaN 和全局 isNaN 的区别

JavaScript 有两个判断 NaN 的方法,名字很像但行为不同。全局 isNaN() 会先把参数转成数字,再判断转换结果是不是 NaN。这意味着 isNaN("hello") 返回 true——不是因为 "hello" 是 NaN,而是因为 Number("hello") 是 NaN。这个行为经常导致误判。

Number.isNaN() 是 ES6 加的,不做任何转换。参数不是 number 类型直接返回 false,只有参数确实是 NaN 这个值时才返回 true。

两种 isNaN 的对比JavaScript
console.log(isNaN(NaN));
console.log(isNaN('hello'));
console.log(isNaN(undefined));
console.log(Number.isNaN(NaN));
console.log(Number.isNaN('hello'));
console.log(Number.isNaN(undefined));
查看输出与解释
true
true
true
true
false
false

前三行全局 isNaN 对 "hello" 和 undefined 都返回 true,因为它们被 Number() 转换后都是 NaN。后三行 Number.isNaN 只对真正的 NaN 返回 true。在实际代码中应该始终用 Number.isNaN。

数组查找和相等算法的关系

NaN 不等于自身这件事还会影响数组查找。indexOf 用的是严格相等 ===,找 NaN 永远返回 -1。includes 用的是 SameValueZero 算法,能识别 NaN。

indexOf 找不到 NaN 但 includes 能JavaScript
console.log([1, NaN, 3].indexOf(NaN));
console.log([1, NaN, 3].includes(NaN));
console.log(Object.is(NaN, NaN));
查看输出与解释
-1
true
true

Object.is 用的是 SameValue 算法,也能识别 NaN。SameValue 和 SameValueZero 的唯一区别是对 +0 和 -0 的处理:SameValue 区分它们,SameValueZero 不区分。Map 和 Set 的键比较用的是 SameValueZero,所以 NaN 可以当 Map 的键,后续用另一个 NaN 也能命中同一个键。 NaN 还有一个特性叫传播性:任何包含 NaN 的算术运算,结果还是 NaN。NaN + 1 是 NaN,NaN > 0 是 false,NaN < 0 也是 false。这意味着一旦计算链里出现了 NaN,后面的结果全部失效。所以拿到 NaN 时不应该简单地替换成 0,而应该追溯是哪一步输入出了问题。

回答前,多想一步

容易答错的地方

用 value === NaN 做判断
这个表达式永远返回 false,不管 value 是什么。面试中写出 if (x === NaN) 会直接暴露对 NaN 特性不了解。应该用 Number.isNaN(x)。
用全局 isNaN 校验用户输入
isNaN("") 返回 false(因为 Number("") 是 0,不是 NaN),isNaN(" ") 也返回 false(纯空白转成 0)。但 isNaN("hello") 返回 true。这些行为混在一起很容易让校验逻辑出 bug。正确做法是先用 Number() 显式转换,再用 Number.isNaN 检查结果,或者用 Number.isFinite 做更严格的校验。
试着用自己的话回答

面试官还会怎么问?

为什么 typeof NaN 是 "number"?

NaN 是 IEEE 754 浮点数标准定义的一个特殊数值,用来表示数值运算失败的结果。它确实属于 Number 类型,不是一个独立的 JavaScript 类型。类型正确不代表值可用,就像 Infinity 也是 "number" 一样。

JSON.stringify 怎么处理 NaN?

输出 null。JSON.parse 后拿到的是 null,原来的 NaN 信息就丢了。如果需要在 JSON 里保留这个语义,得自己约定协议,比如用特定字符串表示。

NaN 可以当 Map 的键吗?

可以。Map 的键比较使用 SameValueZero 算法,能识别 NaN。map.set(NaN, 'value') 之后,map.get(NaN) 能拿到 "value",即使两个 NaN 在 === 下不相等。

从一道题,走向一组知识

把知识连起来

值与类型

怎么用 Object.prototype.toString 做比 typeof 更精确的类型判断?

Object.prototype.toString.call(NaN) 返回 "[object Number]",因为 NaN 的类型确实是 number。

值与类型

字符串是原始类型,为什么还能调用 toUpperCase 这样的方法?

new Number(NaN) 是一个包装对象,typeof 返回 "object" 而不是 "number",类型检查又多了一层复杂度。

值与类型

全局 isFinite 和 Number.isFinite 有什么区别?

Number.isFinite(NaN) 返回 false,可以和 Number.isNaN 配合做数值有效性校验。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • NaN

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. Number.isNaN 和全局 isNaN 的区别
  3. 数组查找和相等算法的关系
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑