前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
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 负零 -0
JavaScript值与类型

什么操作会得到 -0?它和 0 有哪些行为上的区别?

JavaScript 的 Number 保留了 IEEE 754 的正零和负零。-0 === 0 是 true,严格相等分不出来。Object.is(-0, 0) 返回 false,这是最可靠的区分方式。1 / -0 得到 -Infinity,符号通过倒数暴露出来。

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

零的符号在不同层面的可见性

  1. 内存层面符号位记录了正负,-0 和 +0 是不同的二进制值
  2. 比较层面=== 合并两个零,Object.is 区分
  3. 序列化层面String() 和 JSON.stringify 都把 -0 输出成 "0"

大多数业务不需要区分正零和负零,但动画方向、数值算法中的趋近方向可能需要保留这个信息。

核心回答

先记住这个答案

IEEE 754 浮点格式有独立的符号位,即使指数和尾数全部为零,符号位仍然可以是 1,所以存在两个零:+0 和 -0。JavaScript 的 === 特意把它们视为相等,-0 === 0 返回 true。要区分两个零,需要用 Object.is(-0, 0),它返回 false。另外 1 / -0 得到 -Infinity 而 1 / 0 得到 Infinity,通过倒数的符号也能观察到差异。

  • Object.is(-0, 0) 为 false
  • 1 / -0 得到 -Infinity
  • String(-0) 输出 "0",符号丢失
  • Map 和 Set 把 +0 和 -0 当同一个键

怎么产生负零

负零不需要显式写 -0,很多运算会隐式产生它。负数向零舍入、负数乘以零、负数除以 Infinity 都可能得到 -0。

检测负零并观察序列化JavaScript
var neg = -0;
console.log(neg === 0);
console.log(Object.is(neg, -0));
console.log(Object.is(neg, 0));
console.log(1 / neg);
console.log(String(neg));
console.log(JSON.stringify(neg));
查看输出与解释
true
true
false
-Infinity
0
0

第一行说明 === 分不出两个零。Object.is 能区分:Object.is(neg, -0) 是 true,Object.is(neg, 0) 是 false。1 / -0 得到 -Infinity,这也是一种间接检测方式。 最后两行是关键:String(-0) 和 JSON.stringify(-0) 都输出 "0",符号信息在转成文本时丢了。如果你把一个包含 -0 的对象序列化成 JSON 再反序列化,拿回来的就是普通的 0,负零的语义消失了。

Object.is 和其他相等算法怎么处理两个零

JavaScript 有四种相等算法,对 -0 的处理各不相同。=== 和 == 都把两个零当同一个值。Object.is 使用 SameValue 算法,能区分它们。includes、Map、Set 使用的 SameValueZero 算法和 === 一样,不区分两个零。

这意味着如果你用 -0 做 Map 的键,后面用 0 也能命中同一个键。Set 里加了 -0 之后再加 0,集合大小不会增加。在绝大多数业务场景下,这个行为是合理的——你不会希望 0 和 -0 被当成两个不同的值存两份。

但在数值算法里有时候需要保留这个信息。比如某个物理模拟计算速度,-0 表示从负方向趋近静止,+0 表示从正方向趋近静止。如果中间过程把 -0 丢了,后续计算方向就错了。遇到这种场景,在存储和传输时就不能用 JSON 或 String() 转换,需要自己约定编码方式。

回答前,多想一步

容易答错的地方

用 value === -0 检测负零
0 === -0 是 true,所以 value === -0 对正零也会通过,根本区分不了。正确的检测方式是 Object.is(value, -0)。
以为 JSON 往返能保留负零
JSON.stringify(-0) 输出 "0",JSON.parse("0") 得到 0。整个过程中 -0 的符号信息不可逆地丢失了。如果接口需要传递带符号的零,得在协议层另外约定。
试着用自己的话回答

面试官还会怎么问?

Math.sign(-0) 返回什么?

返回 -0,不是 -1。Math.sign 对零保留了原始符号。如果你想用 Math.sign 来判断正负,拿到 -0 时还是没法直接当 -1 用,需要额外处理。

怎么把显示中的 -0 变成 0?

在格式化输出前用 Object.is(value, -0) ? 0 : value 做一次归一化。只在确认业务不需要符号信息时才做,否则会掩盖有意义的数据。

为什么需要两个零?

IEEE 754 的设计初衷是让浮点运算在趋近零时保留方向信息。比如一个很小的负数除以一个很大的正数,数学上趋近于零但从负侧逼近,用 -0 可以记录这个方向。1 / -0 得到 -Infinity 也符合极限的概念:从负侧趋近零的倒数应该是负无穷。

从一道题,走向一组知识

把知识连起来

值与类型

?? 和 || 给默认值有什么区别?什么时候该用哪个?

-0 ?? 1 返回 -0,因为 -0 不是 null 也不是 undefined。-0 || 1 返回 1,因为 -0 是假值。

值与类型

JavaScript 的 Number 在内存里是怎么存的?符号、指数、尾数各占几位?

负零的存在来自 IEEE 754 的符号位设计,理解浮点数的二进制结构就能明白为什么会有两个零。

参考资料

  • JavaScript:值与类型参考资料

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

本题目录
  1. 先记住这个答案
  2. 怎么产生负零
  3. Object.is 和其他相等算法怎么处理两个零
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

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

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