有三个函数可以把非数值转换为数值:
- Number()
- parseInt()
- parseFloat()
第一个函数,转型函数Number()可以用于任何数据类型转换为数值。
而另外两个函数parseInt(),parseFloat()则专门用于把字符串转换成数值。
Number()函数的转换规则如下:
- 如果是Boolean值,true和false将分别被转换成1和0
- 如果是数字值,只是简单的传入和返回
- 如果是null值,返回0
- 如果是undefined,返回NaN
- 如果是字符串,遵循下列规则:
1.如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即“1”会变成1,“123”会变成123,而“0011”会变成11(注意:前导的零被忽略了);
2.如果字符串中包含有效的浮点格式,如“1.1”,则将其转换为对应的浮点数值(同样,也会忽略前导零);
3.如果字符串中包含有效的十六进制格式,例如“0xf”,则将其转换为相同大小的十进制整数值;
4.如果字符串是空的(不包含任何字符,例如“”),则将其转换为0;
5.如果字符串中包含除上述格式之外的字符,则将其转换为NaN。 - 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值
下面给出一些具体的例子:
console.log(Number("")); //0
console.log(Number("Hello ECMAScript!")); //NaN
console.log(Number("0000123")); //123
console.log(Number("-1234")); //-1234
console.log(Number("+1234")); //1234
console.log(Number("0xf")); //15,只有十六进制可以识别转换
console.log(Number(.1)); //0.1
console.log(Number(".1")); //0.1
console.log(Number(1.)); //1
console.log(Number("1.")); //1
/*一些 Number()与 parseInt(),parseFloat()的区别思考:*/
console.log(Number("070")); //70
console.log(Number(070)); //56,自动以8进制方式转换
console.log(Number(1010)); //1010,不能自动以2进制方式转换
console.log(Number("070",8));//70,不存在第二个参数当作基数来说明以哪种进制进行转换
console.log(Number(0xF)); //15,自动以16进制方式转换
console.log(Number("1010",2));//1010,不存在第二个参数当作基数来说明以哪种进制进行转换
由于 Number() 函数再转换字符串时比较复杂而且不够合理,因此在处理整数的时候更常用的是 parseInt() 函数。
parseInt()函数的转换规则如下:
- parseInt()函数在转换字符串时,更多的是看其是否符合数值模式。它会忽略字符串前面的空格,直至找到第一个非空字符。如果第一个字符不是数字字符或者负号,parseInt()就会返回NaN;也就是说,用parseInt()转换空字符串会返回NaN ( Number() 对空字符返回0 )。如果第一个字符是数字字符,parseInt()会继续解析第二个字符,直至解析完所有后续字符或者遇到了一个非数字字符。例如:“1234blue”会被转换为1234,因为“blue”会被完全忽略。类似地,“22.5”会被转换为22,因为小数点并不是有效的数字字符。
- 如果字符串中的第一个字符是数字字符,parseInt()也能够识别出各种整数格式(即十进制,十六进制,但是不具有解析八进制值和二进制的能力,在早期的ECMAScript3 JavaScript引擎中是可以识别解析八进制的)
下面是一些关于parseInt()的具体例子:
console.log(parseInt("1000010")); //二进制无法解析,输出1000010
console.log(parseInt("070")); //八进制无法解析,输出70,前导0被忽略
console.log(parseInt("0xA")); //十六进制可以被解析,输出10
console.log(parseInt("")); //NaN
console.log(parseInt(22.5)); //22
console.log(parseInt("1234.567")); //1234
console.log(parseInt("1234blue")); //1234
console.log(parseInt("blue1234")); //NaN
console.log(parseInt(".1234")); //NaN
为了消除在使用parseInt()函数时可能导致的上述困惑,可以为这个函数提供第二个参数:转换时使用的基数(即多少进制)。如果知道要解析的值是十六进制格式的字符串,那么指定基数16作为第二个参数,可以保证得到正确的结果,例如:
console.log(parseInt("AF",16)); //175,可以省略16进制前导0x
console.log(parseInt("70",8)); //56,可以省略8进制前导0
console.log(parseInt("70",10)); //70,十进制
console.log(parseInt("1010",2)); //10,二进制
指定不同的基数会影响到转换的输出结果。例如:
console.log(parseInt("10",2)); //2,二进制
console.log(parseInt("10",8)); //8,八进制
console.log(parseInt("10",10)); //10,十进制
console.log(parseInt("10",16)); //16,十六进制
因此为了避免错误的解析,我们建议无论在什么情况下都明确指定基数。
parseFloat()函数的转换规则如下:
- 与parseInt()类似,parseFloat()也是从第一个字符( 位置0 )开始解析每个字符。而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。也就是说,字符串中的第一个小数点是有效的,而第二个小数点就是无效的了,因此它后面的字符串将被忽略。举个例子:
console.log(parseFloat("12.34.56")); //12.34
console.log(parseFloat("12.34hello56"));//12.34
console.log(parseFloat(".1234hello567"));//0.1234
console.log(parseFloat("blue123")); //NaN
- 除了第一个小数点有效之外,parseFloat()与parseInt()的第二个区别在于它始终都会忽略前导的零。parseFloat()可以识别前面讨论过的所有浮点数值格式,也包括十进制整数格式。但十六进制格式的字符串则始终会被转换成0。由于parseFloat()只解析十进制值,因此它没有用第二个参数指定基数的用法。最后还有一点:如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后面都是0),parseFloat()会返回整数。下面是几个具体的例子:
console.log(parseFloat("1234blue")); //1234
console.log(parseFloat("1234.")); //1234
console.log(parseFloat("1234.0000")); //1234
console.log(parseFloat("0xA")); //0,十六进制始终转换为0
console.log(parseFloat("3e5")); //300000
console.log(parseFloat("3e-5")); //0.00003
console.log(parseFloat("070")); //70,八进制无法解析,只解析十进制,并且前导0被忽略
console.log(parseFloat("01001001")); //1001001,二进制也无法解析