JavaScript中的数值转换详解

有三个函数可以把非数值转换为数值:

  • 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,二进制也无法解析

猜你喜欢

转载自blog.csdn.net/HHH_LLL/article/details/90781482