所有程序设计语言最重要的特征之一是具有进行类型转换的能力,JavaScript 也不例外。
JavaScript 三种主要基本类型是Boolean、Number 和String,大部分的类型转换是在这三种类型之间相互转换。
JavaScript 中的类型转换方式我把它分成了三类:
- 方法类型转换
- 强制类型转换
- 隐式类型转换
方法类型转换
方法类型转换是使用对象自带的转换方法进行转换
1)转换成字符串:toString()
JavaScript 三种主要基本类型Boolean、Number 和String 的有趣之处在于它们是伪对象,这意味着它们实际上具有属性和方法。
例如,要获得字符串的长度,可以采用下面的代码:
var name = "abc";
alert(name.length); //输出 "3"
尽管 "abc" 是基本类型的字符串,它仍然具有属性length,用于存放字符串的大小。同样的,toString()
方法也是它自带的字符串转换方法。
JavaScript 中所有对象都自带toString()
方法,无论它是伪对象,还是真对象。包括 String 类型,虽然它本身就是字符串,但它也有toString()
方法。
Boolean 类型的toString()
方法只能输出 "true" 或 "false",结果由变量的值决定:
var t = true;
alert(t.toString()); //输出 "true"
var f = false;
alert(f.toString()); //输出 "false"
Number 类型的toString()
方法比较特殊,它有两种模式,即默认模式和基模式。
- 采用默认模式,
toString()
方法只是用相应的字符串输出数字值(无论是整数、浮点数还是科学计数法),如下所示:
var num1 = 10;
var num2 = 10.0;
alert(iNum1.toString()); //输出 "10"
alert(iNum2.toString()); //输出 "10"
在默认模式中,无论最初采用什么表示法声明数字,Number 类型的toString()
方法返回的都是数字的十进制表示。因此,以八进制或十六进制字面量形式声明的数字输出的都是十进制形式的。
- 采用 Number 类型的
toString()
方法的基模式,可以用不同的基输出数字,例如二进制的基是 2,八进制的基是 8,十六进制的基是 16。在toString()
方法中加入基的参数即可。
var num = 10;
alert(num.toString(2)); //输出 "1010"
alert(num.toString(8)); //输出 "12"
alert(num.toString(16)); //输出 "A"
2)转换成数字:parseInt() 、 parseFloat()
parseInt()
parseInt()
方法首先检查第一个字符,判断它是否是个有效数字;如果不是,该方法将返回NaN,不再继续执行其他操作。
如果该字符是有效数字,该方法将继续检查后面的字符,直到发现非有效数字的字符为止,此时parseInt()
将把该字符之前的字符串转换成数字。
字符串中包含的数字字面量会被正确转换为数字,比如 "0xA" 会被正确转换为数字10。不过,字符串 "22.5" 将被转换成 22,因为对于整数来说,小数点是无效字符。
var num1 = parseInt("12345red"); //返回 12345
var num2 = parseInt("0xA"); //返回 10
var num3 = parseInt("56.9"); //返回 56
var num4 = parseInt("red"); //返回 NaN
parseInt()
方法也有基模式:
var num = parseInt("AF", 16); //返回 175
parseFloat()
parseFloat()
方法与parseInt()
方法的处理方式相似,从第一个开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字符之前的字符串转换成整数。
不过,对于这个方法来说,第一个出现的小数点是有效字符。如果有两个小数点,第二个小数点将被看作无效的。parseFloat()
会把这个小数点之前的字符转换成数字。如字符串 "11.22.33" 将被解析成 11.22。
parseFloat()
方法也没有基模式。
var num1 = parseFloat("12345red"); //返回 12345
var num2 = parseFloat("0xA"); //返回 NaN
var num3 = parseFloat("11.2"); //返回 11.2
var num4 = parseFloat("11.22.33"); //返回 11.22
var num5 = parseFloat("0102"); //返回 102
var num6 = parseFloat("red"); //返回 NaN
强制类型转换
JavaScript 中可用的 3 种强制类型转换如下:
- Boolean() :把给定的值转换成 Boolean 型;
- Number() : 把给定的值转换成数字(可以是整数或浮点数);
- String() : 把给定的值转换成字符串;
用这三个函数转换值,将创建一个新值,存放由原始值直接转换成的值。
1)Boolean() 函数
当要转换的值是至少有一个字符的字符串、非 0 数字或对象时,Boolean() 函数将返回true。如果该值是空字符串、数字 0、undefined 或 null,它将返回false。
var b1 = Boolean(""); //false - 空字符串
var b2 = Boolean("hello"); //true - 非空字符串
var b3 = Boolean(50); //true - 非零数字
var b4 = Boolean(null); //false - null
var b5 = Boolean(0); //false - 零
var b6 = Boolean(new object()); //true - 对象
2)Number() 函数
Number()
函数的强制类型转换与parseInt()
和parseFloat()
方法的处理方式相似,只是它转换的是整个值,而不是部分值。
还记得吗,parseInt()
和parseFloat()
方法只转换第一个无效字符之前的字符串,因此 "1.2.3" 将分别被转换为 "1" 和 "1.2"。
用Number()
进行强制类型转换,"1.2.3" 将返回NaN,因为整个字符串值不能转换成数字。如果字符串值能被完整地转换,Number()
将判断是调用parseInt()
方法还是parseFloat()
方法。
var num1 = Number(false) // 0
var num2 = Number(true) // 1
var num3 = Number(undefined) // NaN
var num4 = Number(null) // 0
var num5 = Number("1.2") // 1.2
var num6 = Number("12") // 12
var num7 = Number("1.2.3") // NaN
var num8 = Number(new object()) // NaN
var num9 = Number(50) // 50
3)String() 函数
它可把任何值转换成字符串。
强制转换成字符串和调用toString()
方法的唯一不同之处在于,对null 和undefined 值强制类型转换可以生成字符串而不引发错误。
对于JavaScript 这种若语言来说,强制类型转换非常有用。
隐式类型转换
当运算符在运算时,如果两边数据类型不统一,CPU无法计算,这是编译器会自动将运算符两边的数据做一个数据类型转换,转换成一样的数据类型在进行运算,这种无需程序员手动转换,而由编译器自动转换的方式就称为隐式转换。
隐式转换规则
- 字符串和数字之间进行 减、乘、除、取模运算、比较运算 时,自动把字符串转换为数字。
var temp1 = '1';
var temp2 = 1;
console.log( temp1 - temp2 ) //0
console.log( temp1 * temp2 ) //1
console.log( temp1 / temp2 ) //1
console.log( temp1 % temp2 ) //0
console.log( temp1 > temp2 ) //false
console.log( temp1 < temp2 ) //false
console.log( temp1 == temp2 ) //true
- 进行 加法运算 则是将数字看成字符串进行拼接
console.log( temp1 + temp2 ) //11
// 数值型+字符串=字符串
// 数值型+布尔型=数值型
// 布尔型+字符串=字符串
隐式类型转换规则还有很多很多,这里只列举最常用的。
扩展:如何理解方法类型转换和强制类型转换?
比如toString()
方法,任何一个对象都可以有自己的字符串表达方式,就跟任何物品都可以有自己的名字一样,
而强制类型转换成String,就是将原本不是String 类型的对象转换成String 类型,它不会去调用 toString()
方法。这就相当于强行将物品A当成物品B来使用,跟强行将轮胎当成游泳圈来用是一个道理。