这是我参与更文挑战的第6天,活动详情查看: 更文挑战
NaN
NaN
是 Not a number(不是一个数字)的简称,当我们对一些其他类型的数据转为数字时,或者处理一些关于数字的逻辑运算时,如果不能返回一个正确的值,将返回一个NaN
,而不是抛出一个错误,比如
Number('hello') // NaN
0 / 0 // NaN
复制代码
还有有些有趣的计算,我们可能觉得结果会是NaN,但在js中可能并不如我们想象的那样,比如任何一个大于0的数除以0等于Infinity
,任何一个小于0的数除以0等于0等于-Infinity
,只有+0,-0,0之间相除才会返回NaN
0 / 22 // 0
22 / 0 // Infinity
-22 / 0 // -Infinity
复制代码
需要注意的是,只要涉及到NaN
的数字运算结果都为NaN
NaN + 10 // NaN
NaN - 10 // NaN
NaN * 10 // NaN
NaN / 10 // NaN
NaN % 10 // NaN
复制代码
所以在连续的数学运算中,格外需要注意这个问题,因为一旦其中一个步骤出错,后续的所有计算结果都将为NaN
,并且我们无法通过 if (目标值 === NaN)
进行判断,因为 NaN
并不等于自身,如果我们想要判断一个值是否可以被转化为数字,可以使用js为我们提供的方法 isNaN()
,该函数可以接受任何格式的数据,接收之后会尝试将该数据转为数值,如果不能转换为数值,则会返回 true
,反之则为 false
数值转换
有些时候我们想将其他数据类型转换为数值,js为我们提供了三个方法,分别是 Number()
、 ParseInt()
和 ParseFloat()
,Number)是转型函数,可用于任何数据类型。 后两个函数主要用于将字符串转换为数值。对于同样的参数,这 3个函数执行的操作也不同。
Number()
Number()
函数在将其他数据类型转换为数字类型时主要遵循如下规则
- 布尔值,true转换为1,false转换为0。
- 数值,直接返回
- null,返回0。
- undefined,返回NaN。
- 字符串
- 如果字符串仅包含数值字符,包括数值字符前面带加、减的情况,则转换为一个十进制数值。因此Number(“1”)返回1,Number(“123”)返回123,Number(011返回11(忽略前面的零)。
- 如果字符串包含有效的浮点值格式如,”1.1″,则会转换为相应的浮点值(同样,忽略前面的零)。
- 如果字符串包含有效的十六进制格式如”xP,则会转换为与该十六进制值对应的十进制整数值。
- 如果是空字符串(不包含字符),则返回0。
- 如果字符串包含除上述情况之外的其他字符,则返回NaN。
- 对象,调用 valueOf()方法,并按照上述规则转换返回的值。如果转换结果是NaN,则调用 tostring方法,再按照转换字符串的规则转换。
isNaN()
方法应该用的就是Number()
方法的转换规则,说不定就是调用的Number()
方法,当然,仅是个人猜测,如果有大神知道,欢迎评论。
注意,针对上述转换规则中字符串的第一条规则「如果字符串仅包含数值字符」,在《JavaScript高级程序设计(第四版)》中的原话是这样的「如果字符串包含数值字符」,仅字是我个人加上去的,因为我觉得原文可能对部分人员会造成困扰,误以为只要包含数值就可以转换为数字,其实这样是不对的,例如
Number('10c')
的转换结果就是NaN
parseInt()
parseInt 是英文短句 parse integer 的缩写,意为解析整数。有时候我们需要在一些数字和其他类型的字符混合的字符串中取到数字,例如取到1000ml中的1000,Number显然无法满足我们的需求,这时候我们就可以用 parseInt()
函数,parseInt()
函数通常也可用于浮点数取整
语法:
parseInt(string, radix)
复制代码
参数 | 描述 |
---|---|
string | 必需。要被解析的字符串。 |
radix | 可选。表示要解析的数字的基数(即进制) 该值介于 2 ~ 36 之间。 如果省略该参数或其值为 0,则数字将以 10 为基础来解析。 如果它以 “0x” 或 “0X” 开头,将以 16 为基数。 |
如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。 |
说明:
parseInt()
函数更专注于字符串是否包含数值模式。字符串最前面的空格会被忽略,从第一个非空格字符开始转換。如果第一个字符不是数值字符、加号或减号, parseInt()
立即返回NaN。这意味着空字符串也会返回NaN(这一点跟 Number()
不一样,它返回 0)。如果第一个字符是数值字符、加号或减号,则继续依次检测每个字符,直到字符串末尾,或碰到非数值字符。比如,”1234blue”会被转换为1234,因为”blue”会被完全忽略。类地,”2.5″会被转换为22,因为小数点不是有效的整数字符。
提示,
parseInt()
的第一个参数也支持识别8进制和16进制数字,例如parseInt(017)
识别为15,但是它不支持识别字符串类型的8进制,例如parseInt('017')
识别为17,但是字符串类型的16进制可以识别,例如parseInt('0x17')
识别为23
parseFloat()
parseFloat()
函数与 parseInt()
函数类似,都是从位置0开始检测,不同的是,它支持小数,所以它检测到的第一个小数点是有效的,但是第二个小数点就无效了
parseFloat('10.15.3') // 10.15
复制代码
另一个不同的地方是,他不支持识别字符串类型的16进制数值,例如 parseFloat('0x17')
会被识别为0
还有一个不同的地方,由于 parseFloat()
支持识别小数点,所以它支持科学计数法
parseFloat('3.125e7') // 31250000
复制代码