昨天看到一个面试题:如何完成 isNaN()
要领?
细细研讨了一下 NaN
,发明这个东西不经常运用,坑却非常多,很有 “茴” 字有几种写法的以为,这里记录下总结的东西吧。
NaN
是什么
NaN
即 Not a Number(非数值),但它是一个特别的数值,所以:
typeof(NaN) // "number"
编码时很少直接运用 NaN
,通常是在盘算失利时,作为 Math
的某个要领的返回值涌现的。
它有两个主要的性子:
-
NaN
与任何值都不相称,包含NaN
自身:
alert(NaN == NaN) // false
alert(NaN === NaN) // false
- 任何触及
NaN
的操纵都邑返回NaN
。
哪些状况会发生NaN
?
1. 盘算
JS 在举行加减乘除运算之前,会先挪用 Number()
要领,将非数值的运算项转化为数值,假如转换失利就返回NaN
,比方:
1-'a'; // NaN
首先是实行Number('a')
,不能胜利转化为数值,返回NaN
,再应用NaN
的第二条性子:任何触及 NaN
的操纵都邑返回NaN
,所以终究的效果是NaN
。
2. 范例转换
当一个值不能被Number
,parseInt
,parseFloat
胜利转换为数值,就返回NaN
,举例:
Number('123.456abc'); // NaN
parseInt('123.456abc'); // 123
parseFloat('123.456abc'); // 123.456
Number('abc'); // NaN
parseInt('abc'); // NaN
parseFloat('abc'); // NaN
Number([]); // 0
parseInt([]); // NaN
parseFloat([]); // NaN
Number(''); // 0
parseInt(''); // NaN
parseFloat(''); // NaN
Number({}); // NaN
parseInt({}); // NaN
parseFloat({}); // NaN
这里要注意三者之间的差别,我的明白是 parseInt
,parseFloat
会只管将参数值转化为数值。
关于isNaN()
isNaN
是window
对象的一个要领,比较诡异的是:isNaN(x)
并非推断参数x
自身是否是NaN
,而是推断Number(x)
是否是NaN
。也就是说先用Number()
去转化参数,再去推断转化的效果。返回的效果是一个布尔值。
isNaN(NaN); // true
isNaN(123); // false
isNaN('abc'); //true
isNaN('123abc'); //true
isNaN({}); // true,由于Number({})=NaN
isNaN(''); // false, 由于Number('')=0
isNaN([]); // false,由于Number([])=0
能够看到末了, 空字符串''
和 空数组[]
明显黑白数值,而isNaN
返回了false
,缘由就是Number
转换在作祟,这点照样很诡异的…所以我挑选慎用…
那末isNaN
是怎样完成的呢,道理就是应用NaN
的第一条性子:NaN
与任何值都不相称,包含NaN
自身。
var isNaNA = function(value) {
var n = Number(value);
return n !== n;
};
先用Number()
转换参数,再推断转换后的效果是否是不即是自身。
而 MDN 上给的完成体式格局是如许的:
var isNaNB = function(value) {
var n = parseInt(value);
return n !== n;
};
我以为是有题目的,由于:
isNaN('123abc'); // true
isNaNA('123abc'); // true
isNaNB('123abc'); // false
Number.isNaN()
ES6 中的Number.isNaN()
是一个推断NaN
的升级版,和isNaN()
差别的是,Number.isNaN()
不会强迫转化参数,直接对参数自身做推断,如许只要参数显现即是NaN
,才会返回true
Number.isNaN(NaN); // true,其他状况都返回 false
它的完成道理是:
function isNaNC (value) {
return typeof(value) === "number" && isNaN(value);
}
算了,照样不纠结了….