今天在写代码时,使用isNaN
时,ts提示用Number.isNaN
替代。替换之后,并没有得到预期的结果,才发现两者是有不同的。
isNaN(undefined) // true
Number.isNaN(undefined) //false
复制代码
查阅了相关的问题,想弄明白两者有何不同。在MDN上对全局的isNaN
的解释是:
The global NaN property is a value representing Not-A-Number.
也就是全局的isNaN
只是检验一个值是否 不是一个数字
。isNaN
的全称是“is Not a Number”,从字面意思也可以理解它的作用。
但是,如果要判断一个值是否严格等于NaN,全局的isNaN
貌似就无法做到了,因为传进去任何不能转化成数字的值,都会得到true
。因为全局的isNaN
会把传入的值做类型转换,先转换成数字型,再判断是否==NaN
。
isNaN(NaN) //true
isNaN('123') //false,可转换成number
isNaN(true) //false,可转换成number
isNaN('this is a str') //true,转换成数字是NaN
isNaN(undefined) //true, undefined转换成数字是NaN
复制代码
很显然字符串并不是一个数字,也不是NaN。为了纠正这个bug,ES6中提供了Number.isNaN
用于判断一个值是否严格等于NaN。
isNaN(NaN) //true
Number.isNaN(NaN) //true
isNaN('this is a str') // true
Number.isNaN('this is a str') //false
isNaN(undefined) // true
Number.isNaN(undefined) //false
复制代码
NaN!==NaN
parseInt(5/'d') === Number('ddd') // false
NaN === NaN // false
复制代码
NaN只是Number上的一个静态属性,可以通过Number.NaN
来获得一个NaN。Number('ddd')
运算后会得到NaN, 它只是为了告诉你这个值不是一个数字,一种表示方法,而非一个精准有效的值,因此NaN不能参与计算,也无法与自身比较。所以,也可以说NaN具有与自身不相等的特性。
如何判断两个NaN相等
在ES5中提供了Object.is()方法,用于判断两个值是否属于同一个值,而此方法可用于NaN是否相等的判断,比如
Object.is(NaN, NaN); // true
复制代码
ES6中Number.isNaN
的polyfill
if (!Number.isNaN) {
Number.isNaN = function(n) {
return (
typeof n === 'number' && window.isNaN(n)
);
};
}
复制代码
另一种polyfill,使用NaN不等于他自身的特性:
if (!Number.isNaN) {
Number.isNaN = function(n) {
return n !== n;
};
}
复制代码
参考:
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END