前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
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 热点
旧版
首页程序员面试题库一元加号 类型转换 Number()
JavaScript值与类型

一元加号 +x 和 Number(x) 有什么区别?

对绝大多数值,+x 和 Number(x) 结果一模一样,都走规范里的 ToNumber 转换,+'' 和 Number('') 都是 0。真正的区别只有一处:遇到 BigInt,Number(10n) 返回 10,+10n 抛 TypeError。

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

两种写法的异同

  1. 相同的规则都按 ToNumber 转:null 是 0,undefined 是 NaN,对象先转原始值再转数字
  2. BigInt 的差别Number() 专门处理了 BigInt,一元 + 没有,会抛 TypeError
  3. 可读性+x 短,但容易被看漏;Number(x) 意图明确,适合写在业务代码里

Number(x) 和 new Number(x) 是两回事。前者返回原始数字,后者返回包装对象,typeof 是 object,而且 new Number(0) 是真值。

核心回答

先记住这个答案

一元加号 +x 和 Number(x) 在规范里调用的是同一个抽象操作 ToNumber,所以对字符串、布尔、null、undefined、数组和普通对象,结果完全一样。空字符串两者都转成 0,'12px' 两者都是 NaN。唯一需要记住的差别是 BigInt:Number(10n) 得到 10,+10n 会抛 TypeError。日常开发中两者可以互换,团队代码里更推荐写 Number(x),因为一个孤零零的加号很容易在阅读时被忽略。

  • +x 和 Number(x) 转换规则相同,结果一致
  • 空串、空白串转成 0,'12px' 转成 NaN
  • 一元加号不能直接处理 BigInt
  • 带单位文本可用 parseFloat 解析前缀

常见输入的转换结果

把一组典型输入分别用两种写法转一遍,放在一起对照,就能看出它们是同一套规则。

两种写法并排对照JavaScript
const inputs = ['42', ' 3.5 ', '', '12px', '0x1f', '1e3', null, undefined, true, [], [7], {}]
for (const v of inputs) {
  // 第一列是原值,后两列分别是 +v 和 Number(v)
  console.log(JSON.stringify(v), '|', +v, '|', Number(v))
}
查看输出与解释
"42" | 42 | 42
" 3.5 " | 3.5 | 3.5
"" | 0 | 0
"12px" | NaN | NaN
"0x1f" | 31 | 31
"1e3" | 1000 | 1000
null | 0 | 0
undefined | NaN | NaN
true | 1 | 1
[] | 0 | 0
[7] | 7 | 7
{} | NaN | NaN

字符串的规则是:先去掉首尾空白,剩下的必须整体是一个合法数字字面量,否则就是 NaN。所以 ' 3.5 ' 能转,'12px' 不行。空字符串和纯空白字符串是特例,都转成 0,这在处理表单输入时经常坑人:用户什么都没填,你却拿到了一个合法的 0。 数组和对象会先转成原始值。[] 转成空字符串再变成 0,[7] 转成 '7' 再变成 7,{} 转成 '[object Object]',只能是 NaN。

唯一的差别:BigInt

BigInt 是 ES2020 加入的任意精度整数类型。规范在设计时刻意没让一元加号支持它,原因是 asm.js 这类老代码用 +x 来表示「这一定是个 Number」,如果 + 对 BigInt 静默成功,就破坏了这个约定。

转换 BigIntJavaScript
console.log(Number(10n)) // BigInt 可以显式转成数字
try {
  console.log(+10n)
} catch (e) {
  console.log(e.name) // 一元加号不接受 BigInt
}
console.log(Number(), +undefined) // 不传参是 0,undefined 是 NaN
console.log(typeof Number('5'), typeof new Number('5'))
查看输出与解释
10
TypeError
0 NaN
number object

所以如果某个函数可能收到 BigInt,比如处理后端返回的大整数 ID,就只能用 Number(),并且要清楚超过 Number.MAX_SAFE_INTEGER 的部分会丢精度。

Number() 不传参数时
Number() 什么都不传返回 0,而 Number(undefined) 和 +undefined 都是 NaN。这个差别来自函数本身对「参数个数为 0」的特殊处理,和转换规则无关,平时很少遇到,但面试偶尔会问。

什么时候用哪一个

一元加号常见于追求简短的地方:+new Date() 拿时间戳,list.sort((a, b) => +a.price - +b.price),或者把 URL 参数里的 '3' 转成 3。这些场景用 + 没问题,但在多人维护的业务代码里,Number(value) 读起来一目了然,也能避开 a + +b 这种需要停下来想一想的写法。

和 parseInt、parseFloat 的分工
+'12px' 是 NaN,parseInt('12px', 10) 是 12。前者要求整个字符串都是数字,后者从头读到第一个非法字符为止。所以处理 CSS 值、带单位的字符串用 parseFloat;校验用户输入是否是合法数字,用 Number() 加 Number.isNaN 判断更严格。另外 parseInt('') 是 NaN,而 Number('') 是 0,空输入的处理结果正好相反。
回答前,多想一步

容易答错的地方

以为 +'' 和 Number('') 结果不同
两者都是 0。真正和它们不同的是 parseInt(''),结果是 NaN。把空字符串当成「用户没填」的场景,要先判断 value.trim() === '',不能靠转换结果判断。
把 Number(x) 和 new Number(x) 混为一谈
不带 new 调用是类型转换,返回原始数字。带 new 会创建包装对象,new Number(0) 在 if 里是真值,new Number(1) === 1 为假。实际代码里几乎没有理由使用 new Number。
以为一元加号什么都能转
除了 BigInt,+Symbol() 和 Number(Symbol()) 也都会抛 TypeError,Symbol 不能被隐式或显式地转成数字。
试着用自己的话回答

面试官还会怎么问?

+[]、+{}、+[1, 2] 分别是什么?

分别是 0、NaN、NaN。数组转原始值时调用 toString,[] 是空串,所以是 0;[1, 2] 是 '1,2',不是合法数字;普通对象是 '[object Object]',也是 NaN。

'3' - 1 和 '3' + 1 为什么结果不一样?

减号只有数学含义,会把两边都转成数字,得到 2。加号在任一边是字符串时做拼接,得到 '31'。想让加号做加法,可以写 +'3' + 1 或 Number('3') + 1。

怎么判断一个字符串是不是合法数字?

Number(str) 转完后用 Number.isNaN 判断,同时单独排除空串和纯空白的情况,因为它们会被转成 0。如果还要求是有限数,再加 Number.isFinite,这样 'Infinity' 也会被挡掉。

从一道题,走向一组知识

把知识连起来

值与类型

Object.is 和 === 有什么区别?什么时候非用 Object.is 不可?

转换失败得到的 NaN 用 === 判断不出来,要用 Number.isNaN 或 Object.is。

值与类型

字符串和数字、布尔值用加号拼接时,到底是怎么转换的?

一元 + 是转数字,二元 + 遇到字符串却是拼接,'1' + +'2' 这类表达式要两题一起看。

参考资料

  • JavaScript:值与类型参考资料

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

本题目录
  1. 先记住这个答案
  2. 常见输入的转换结果
  3. 唯一的差别:BigInt
  4. 什么时候用哪一个
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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