# ECMAScript 类型转换

所有程序设计语言最重要的特征之一是具有进行类型转换的能力。

ECMAScript 给开发者提供了大量简单的类型转换方法。

大部分类型具有进行简单转换的方法，还有几个全局方法可以用于更复杂的转换。无论哪种情况，在 ECMAScript 中，类型转换都是简短的一步操作。

## 转换成字符串

ECMAScript 的 Boolean 值、数字和字符串的原始值的有趣之处在于它们是伪对象，这意味着它们实际上具有属性和方法。

例如，要获得字符串的长度，可以采用下面的代码：

    var sColor = "red";
    alert(sColor.length);	//输出 "3"

尽管 "red" 是原始类型的字符串，它仍然具有属性 length，用于存放字符串的大小。

总而言之，3 种主要的原始类型 Boolean 值、数字和字符串都有 toString() 方法，可以把它们的值转换成字符串。

提示：您也许会问，“字符串还有 toString() 方法吗，这不是多余吗？”是的，的确如此，不过 ECMAScript 定义所有对象都有 toString() 方法，无论它是伪对象，还是真对象。因为 String 类型属于伪对象，所以它一定有 toString() 方法。

Boolean 类型的 toString() 方法只是输出 "true" 或 "false"，结果由变量的值决定：

    var bFound = false;
    alert(bFound.toString());	//输出 "false"

Number 类型的 toString() 方法比较特殊，它有两种模式，即默认模式和基模式。采用默认模式，toString() 方法只是用相应的字符串输出数字值（无论是整数、浮点数还是科学计数法），如下所示：

    var iNum1 = 10;
    var iNum2 = 10.0;
    alert(iNum1.toString());	//输出 "10"
    alert(iNum2.toString());	//输出 "10"

注释：在默认模式中，无论最初采用什么表示法声明数字，Number 类型的 toString() 方法返回的都是数字的十进制表示。因此，以八进制或十六进制字面量形式声明的数字输出的都是十进制形式的。

采用 Number 类型的 toString() 方法的基模式，可以用不同的基输出数字，例如二进制的基是 2，八进制的基是 8，十六进制的基是 16。

基只是要转换成的基数的另一种加法而已，它是 toString() 方法的参数：

    var iNum = 10;
    alert(iNum.toString(2));	//输出 "1010"
    alert(iNum.toString(8));	//输出 "12"
    alert(iNum.toString(16));	//输出 "A"

在前面的示例中，以 3 种不同的形式输出了数字 10，即二进制形式、八进制形式和十六进制形式。HTML 采用十六进制表示每种颜色，在 HTML 中处理数字时这种功能非常有用。

注释：对数字调用 toString(10) 与调用 toString() 相同，它们返回的都是该数字的十进制形式。

#### 参阅：

请参阅 JavaScript 参考手册提供的有关 toString() 方法的详细信息：

- arrayObject.toString()
- booleanObject.toString()
- dateObject.toString()
- NumberObject.toString()
- stringObject.toString()

## 转换成数字

ECMAScript 提供了两种把非数字的原始值转换成数字的方法，即 parseInt() 和 parseFloat()。

正如您可能想到的，前者把值转换成整数，后者把值转换成浮点数。只有对 String 类型调用这些方法，它们才能正确运行；对其他类型返回的都是 NaN。

### parseInt()

在判断字符串是否是数字值前，parseInt() 和 parseFloat() 都会仔细分析该字符串。

parseInt() 方法首先查看位置 0 处的字符，判断它是否是个有效数字；如果不是，该方法将返回 NaN，不再继续执行其他操作。但如果该字符是有效数字，该方法将查看位置 1 处的字符，进行同样的测试。这一过程将持续到发现非有效数字的字符为止，此时 parseInt() 将把该字符之前的字符串转换成数字。

例如，如果要把字符串 "12345red" 转换成整数，那么 parseInt() 将返回 12345，因为当它检查到字符 r 时，就会停止检测过程。

字符串中包含的数字字面量会被正确转换为数字，比如 "0xA" 会被正确转换为数字 10。不过，字符串 "22.5" 将被转换成 22，因为对于整数来说，小数点是无效字符。

一些示例如下：

    var iNum1 = parseInt("12345red");	//返回 12345
    var iNum1 = parseInt("0xA");	//返回 10
    var iNum1 = parseInt("56.9");	//返回 56
    var iNum1 = parseInt("red");	//返回 NaN

parseInt() 方法还有基模式，可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。基是由 parseInt() 方法的第二个参数指定的，所以要解析十六进制的值，需如下调用 parseInt() 方法：

    var iNum1 = parseInt("AF", 16);	//返回 175

当然，对二进制、八进制甚至十进制（默认模式），都可以这样调用 parseInt() 方法：

    var iNum1 = parseInt("10", 2);	//返回 2
    var iNum2 = parseInt("10", 8);	//返回 8
    var iNum3 = parseInt("10", 10);	//返回 10

如果十进制数包含前导 0，那么最好采用基数 10，这样才不会意外地得到八进制的值。例如：

    var iNum1 = parseInt("010");	//返回 8
    var iNum2 = parseInt("010", 8);	//返回 8
    var iNum3 = parseInt("010", 10);	//返回 10

在这段代码中，两行代码都把字符 "010" 解析成一个数字。第一行代码把这个字符串看作八进制的值，解析它的方式与第二行代码（声明基数为 8）相同。最后一行代码声明基数为 10，所以 iNum3 最后等于 10。

#### 参阅

请参阅 JavaScript 参考手册提供的有关 parseInt() 方法的详细信息：parseInt()。

### parseFloat()

parseFloat() 方法与 parseInt() 方法的处理方式相似，从位置 0 开始查看每个字符，直到找到第一个非有效的字符为止，然后把该字符之前的字符串转换成整数。

不过，对于这个方法来说，第一个出现的小数点是有效字符。如果有两个小数点，第二个小数点将被看作无效的。parseFloat() 会把这个小数点之前的字符转换成数字。这意味着字符串 "11.22.33" 将被解析成 11.22。

使用 parseFloat() 方法的另一不同之处在于，字符串必须以十进制形式表示浮点数，而不是用八进制或十六进制。该方法会忽略前导 0，所以八进制数 0102 将被解析为 102。对于十六进制数 0xA，该方法将返回 NaN，因为在浮点数中，x 不是有效字符。（注释：经测试，具体的浏览器实现会返回 0，而不是 NaN。）

此外，parseFloat() 方法也没有基模式。

下面是使用 parseFloat() 方法的一些示例：

    var fNum1 = parseFloat("12345red");	//返回 12345
    var fNum2 = parseFloat("0xA");	//返回 NaN
    var fNum3 = parseFloat("11.2");	//返回 11.2
    var fNum4 = parseFloat("11.22.33");	//返回 11.22
    var fNum5 = parseFloat("0102");	//返回 102
    var fNum1 = parseFloat("red");	//返回 NaN

亲自试一试

#### 参阅

请参阅 JavaScript 参考手册提供的有关 parseFloat() 方法的详细信息：parseFloat()。

## 强制类型转换

您还可以使用强制类型转换（type casting）来处理转换值的类型。使用强制类型转换可以访问特定的值，即使它是另一种类型的。

编者注：cast 有“铸造”之意，很贴合“强制转换”的意思。

ECMAScript 中可用的 3 种强制类型转换如下：

- Boolean(value) - 把给定的值转换成 Boolean 型；
- Number(value) - 把给定的值转换成数字（可以是整数或浮点数）；
- String(value) - 把给定的值转换成字符串；

用这三个函数之一转换值，将创建一个新值，存放由原始值直接转换成的值。这会造成意想不到的后果。

### Boolean() 函数

当要转换的值是至少有一个字符的字符串、非 0 数字或对象时，Boolean() 函数将返回 true。如果该值是空字符串、数字 0、undefined 或 null，它将返回 false。

可以用下面的代码测试 Boolean 型的强制类型转换：

    var b1 = Boolean("");		//false - 空字符串
    var b2 = Boolean("hello");		//true - 非空字符串
    var b1 = Boolean(50);		//true - 非零数字
    var b1 = Boolean(null);		//false - null
    var b1 = Boolean(0);		//false - 零
    var b1 = Boolean(new object());	//true - 对象

### Number() 函数

Number() 函数的强制类型转换与 parseInt() 和 parseFloat() 方法的处理方式相似，只是它转换的是整个值，而不是部分值。

还记得吗，parseInt() 和 parseFloat() 方法只转换第一个无效字符之前的字符串，因此 "1.2.3" 将分别被转换为 "1" 和 "1.2"。

用 Number() 进行强制类型转换，"1.2.3" 将返回 NaN，因为整个字符串值不能转换成数字。如果字符串值能被完整地转换，Number() 将判断是调用 parseInt() 方法还是 parseFloat() 方法。

下表说明了对不同的值调用 Number() 方法会发生的情况：

用法 | 结果
--- | ---
Number(false) | 0
Number(true) | 1
Number(undefined) | NaN
Number(null) | 0
Number("1.2") | 1.2
Number("12") | 12
Number("1.2.3") | NaN
Number(new object()) | NaN
Number(50) | 50

### String() 函数

最后一种强制类型转换方法 String() 是最简单的，因为它可把任何值转换成字符串。

要执行这种强制类型转换，只需要调用作为参数传递进来的值的 toString() 方法，即把 12 转换成 "12"，把 true 转换成 "true"，把 false 转换成 "false"，以此类推。

强制转换成字符串和调用 toString() 方法的唯一不同之处在于，对 null 和 undefined 值强制类型转换可以生成字符串而不引发错误：

    var s1 = String(null);	//"null"
    var oNull = null;
    var s2 = oNull.toString();	//会引发错误

在处理 ECMAScript 这样的弱类型语言时，强制类型转换非常有用，不过应该确保使用值的正确。