数值转换
有3个函数可以将非数值转换为数值:Number() 、parseInt() 和parseFloat() 。Number() 是转型函数,可用于任何数据类型。后两个函数主要用于将字符串转换为数值,对于同样的参数,这3个函数执行的操作也不同
Number() 函数基于如下规则执行转换
- 布尔值,true转换为1,false转换为0
- 数值,直接返回
- null,返回0
- undefined,返回NaN
- 字符串,包含以下规则
- 如果字符串包含数字字符,包括数值字符前面带加、减号的情况,则转换为一个十进制的数值
Number("1"); // 1 Number("123"); // 123 Number("011"); // 11 ,省略前面的0
2.如果字符串包含有效的浮点值格式为1.1,则会转换为相应的浮点值(同样的,忽略前面的零)
3.如果字符串包含有效的十六进制格式如0xf,则会转换为与该十六进制相对应的十进制整数
4.如果是空字符串(不包含字符),则返回0
5.如果字符串包含上述情况之外的其他字符,则返回NaN
- 对象,调用valueOf() 方法,并按照上述规则转换返回的值,如果转换结果是NaN,则调用toString()方法,再按照转换字符串的规则转换
<script> let num1 = Number("Hello world"); // NaN let num2 = Number(""); // 0 let num3 = Number("000011"); // 11 let num4 = Number(true); // 1 </script>
可以看到,字符串Hello world
转换之后是NaN,因为它找不到对应的数值,空字符串转换后是0,字符串000011
转换之后是11
,因为前面的0被忽略了
我们考虑到Number() 函数转换为字符串相对复杂且有点反常规,我们通常在需要得到整数钱可以优先使用parseInt()函数。parseInt()函数转换字符串是否包含数值模式。字符串最前面的空格会被忽略,从第一个非空格字符开始转换,如果第一个字符不是数值字符、加号、减号,parseInt() 立即返回NaN。这意味着空字符串也会继续返回NaN(这一点跟Number() 不一样,它返回0)。如果第一个字符是数值字符、加号或减号,则继续依次检测每个字符,直到字符串末尾或者碰到非数值字符,比如1234blue
会转换成1234
,因为blue会被完全忽略。类似的,22.5会被转换为22,小数不是有效的整数字符
假设字符串中的第一个字符是数字字符,parseInt() 函数也能识别不同的整数格式(十进制、八进制、十六进制)。换句话说,如果字符串以0x开头,就会被解释成十六进制,如果字符串以0开头,且紧跟着数值字符,在非严格模式下会被某些实现解释为八进制整数
<script> let num1 = parseInt("12345blue"); // 12345 let num2 = parseInt(""); // NaN let num3 = parseInt("0xA"); //10 let num4 = parseInt("22.5"); //22 let num5 = parseInt("70"); //70 let num6 = parseInt("0xf"); //15 </script>
不同的数值格式很容易混淆,因此parseInt() 也接收第二个参数,用于指定底数(进制数)。如果知道要解析的值是十六进制,那么可以传入16作为第二个参数
<script> let num1 = parseInt("AF",16); // 175 let num2 = parseInt("AF"); // NaN </script>
在这个例子中,第一个转换是正确的,但是第二个转换失败了。区别在于第一次传入了进制数作为参数,告诉parseInt() 要解析的是一个十六进制字符串;而第二个转换检测到第一个字符就是非数值字符,随即自动停止并返回NaN
通过第二个参数,可以极大扩展转换后获得的结果类型,比如
let num1 = parseInt("10",2); // 2 let num2 = parseInt("10",8); // 8 let num3 = parseInt("10",10); // 10 let num4 = parseInt("10",16); // 16
因为不传底数参数相当于让parseInt() 自己决定如何解析,所以为了避免解析出错,始终建议传给它第二个参数
注意注意!
多数情况下解析的都是十进制数,所以第二个参数就要写入10
parseFloat() 函数的工作方式跟parseInt() 函数类似,都是从位置0开始检测每个字符。同样,它也是解析到字符串末尾或者计息到一个无效的浮点数值为止,这意味着第一次出现的小数点是有效的,但是第二次出现的小数点就无效了。此时字符串的剩余字符都会被忽略。
parseFloat() 函数的另一个不同之处在于,它始终忽略字符串开头的零。这个函数始终能识别前面讨论的所有浮点格式,以及十进制格式(开头的零始终被忽略)。十六进制始终会返回0,。因为parseFloat() 只解析十进制,因此不能指定底数。最后,如果字符串表示整数(没有小数点或者小数点后面只有一个零)则parseFloat() 返回整数
<script> let num1 = parseFloat("1234blue"); // 1234 let num2 = parseFloat("0xA"); // 0 let num3 = parseFloat("22.5"); // 22.5 let num4 = parseFloat("22.34.5"); // 22.34 let num5 = parseFloat("0908.5"); // 908.5 let num6 = parseFloat("3.125e7"); // 32150000 </script>