javascript 判断正负0
ES 2015/ ES 6 新增了一个方法用于 javascript 相等性判断 – Object.is()
。它与之前的相等比较运算符有什么不同呢?
三种不同的值比较操作
- 抽象相等比较 (==):将执行类型转换再进行比较,特殊地:Null 与 undefined 返回 true, 任何类型与 NaN返回 false, +0与-0为true.
- 严格等于运算符(===):不会执行类型转换,类型不一致返回false,特殊地:NaN与NaN为false,+0与-0为true.
Object.is
: 基本与全等(===)相同,特殊地:NaN与NaN为true,+0与-0为false.
+0 与 -0 到底是否相同
答案是不同。
一般地,使用全等运算符(===)是比较安全的操作,但是正负零是返回true,容易让人有一种存在一种0的错觉。
在高版本的Node中,正负0的符号是区别对待的,正0显示为0,负0显示为 -0。
在除法中,1/+0
为 +Infinity
, 1/-0
为 -Infinity
,而 +Infinity === -Infinity
返回 false.
同时根据 javascript 64位双精度浮点数,第 1 位是正负数符号位(sign),0代表正数,1代表负数,中间的 11 位存储指数(exponent),用来表示次方数,最后的 52 位是尾数(mantissa),超出的部分自动进一舍零。所以正负0的表示是不同的。
疑问:如果正负 0 确实是两个数,为什么全等判断中会相同?
通过查看规范,
比较 x === y,x 和 y 为值,需要产出 true 或 false。比较过程如下:
- 如果 Type(x) 与 Type(y) 的结果不一致,返回 false。
- 如果 Type(x) 结果为 Undefined,返回 true。
- 如果 Type(x) 结果为 Null,返回 true。
- 如果 Type(x) 结果为 Number,则
- 如果 x 为 NaN,返回 false。
- 如果 y 为 NaN,返回 false。
- 如果 x 与 y 为同一个数字,返回 true。
- 如果 x 为 +0,y 为 -0,返回 true。
- 如果 x 为 -0,y 为 +0,返回 true。
- 返回 false。
- 如果 Type(x) 结果为 String,如果 x 与 y 为完全相同的字符序列(相同的长度和相同的字符对应相同的位置),返回 true,否则,返回 false。
- 如果 Type(x) 结果为 Boolean,如果 x 与 y 都为 true 或 false,则返回 true,否则,返回 false。
- 如果 x 和 y 引用到同一个 Object 对象,返回 true,否则,返回 false。
全等运算符虽然没有作类型转换,但也是针对 NaN
、+0
、-0
作了特殊处理。
区分正负零的方法
通过以上知识点,可以总结出:
1、通过除 0 法判断:
const isNegativeZero = num => num === 0 && 1/num === -Infinity;
2、通过 object.is
const isNegativeZero = num => Object.is(num, -0);
总结
Object.is
是ES2015 新特性,与 ===
不一样的是:它可以正确分辨 正负零 及 NaN。