特殊的数字
NaN"不是数字的数字"
NaN概念:数学运算的操作数不是数字类型,无法返回一个有效数字。例如:a/'dw'
let a = 2 / "dw";
console.log(a); //NaN
console.log(typeof a === "number"); //true
console.log(NaN === NaN); //false
可以看到对NaN进行typeof的类型判断居然是number类型。
并且在JS里,NaN唯一一个与自身不全等(===) 。
关于isNaN()这个函数会检查参数是否不是NaN,也不是数字。
let a = 2 / "dw";
console.log(isNaN(a)); //true
console.log(isNaN(1)); //false
console.log(isNaN("1")); //false
console.log(isNaN("a")); //true
这里第三行和第四行很奇怪,为什么同样是字符串会有两种结果?因为isNaN这个函数会将参数转换为数字转换不成功就自然是NaN,所以最后两行有差异。
那么,如何精准判断一个值是不是NaN呢?JS给了我们一个方法Number.isNaN()
let a = 2 / "dw";
console.log(Number.isNaN(a));//true
console.log(Number.isNaN(1));//false
console.log(Number.isNaN("1"));//false
console.log(Number.isNaN("a"));//false
可以看到最后一行变成了false,判断完全正确。
Number.isNaN()是如何实现的呢?
这个函数主要是解决isNaN函数对参数的强制转换为数字的问题,可以对参数类型进行判断限制。
比如:
let a = 2 / "dw";
//这里我模拟Number.isNaN()取名为iNaN
function iNaN(arg) {
return typeof arg === "number" && isNaN(arg);
}
console.log(iNaN(a));//true
console.log(iNaN(1));//false
console.log(iNaN("1"));//false
console.log(iNaN("a"));//false
可以达到预期效果,
还可以利用他与自身不等实现。
function iNaN(arg) {
return arg !== arg;
}
结果与上面一样。
-0
console.log(0 === 0); //true
console.log(-0 === 0); //true
console.log(-0 === +0); //true
console.log(-0 == +0); //true
console.log(-0 == +0); //true
console.log(-0 > 0); //false
console.log(-0 < 0); //false
console.log(Object.is(-0, 0));//false
console.log(Object.is(-0, +0));//false
-0,0这两个数在js中是存在的,基本的相等符号(==和===)对于这三个数都是true
Object.is()可以判断两个值是不是相同值,可以分出区别,
console.log(Object.is(NaN, NaN)); 可以判断NaN
[详情见MDN](Object.is() - JavaScript | MDN (mozilla.org))
应用:这个值可以在需要判断0值时上升还是下降趋势时进行判断,比如股票,地理方向。更语义化。
实现Object.is()
实现思路:解决NaN与自身不等和-0与0相等的难题,其他都交给”===“处理即可。
Object.is = function (a, b) {
let aIsNegZero = isNegZero(a);
let bIsNegZero = isNegZero(b);
if (aIsNegZero || bIsNegZero) {
return aIsNegZero && bIsNegZero;
}
else if (isNanValue(a) && isNanValue(b)) {
return true;
}
else if (a === b) {
return true;
}
else return false;
// 判断参数是不是-0
function isNegZero(x) {
return x === 0 && 2 / x === -Infinity;
}
//判断参数是不是NaN
function isNanValue(x) {
return x !== x;
}
};