|
2.4 ECMAScript类型转换 |
本节介绍关于ECMAScript类型转换的知识,ECMAScript语法为设计人员提供既丰富又简单的类型转换方法,类型转换基本可以通过一步操作即可完成。ECMAScript类型转换同样是语法基础中非常重要的一部分。
根据Ecma-262规范中的定义,ECMAScript语法提供一个toString(argument)函数方法用于实现将数据类型转换成字符串的功能,该方法适用于Boolean原始类型、Number原始类型和String原始类型的原始值。关于toString(argument)函数方法的语法说明如下:
toString(argument); // TODO: 用于实现将数据类型转换成字符串的功能
其中,“argument”参数是可选的,当需要转换成特殊类型的字符串时,可以通过定义该参数来实现。
下面,先看第一个使用toString(argument)函数方法将数据类型转换成字符串操作的代码示例(详见源代码ch02目录中ch02-js-toString-a.html文件)。
【代码2-27】
01 <script type="text/javascript"> 02 var v_str = "toString()"; 03 console.log(v_str.toString()); 04 var v_b_t = true; 05 console.log(v_b_t.toString()); 06 var v_b_f = false; 07 console.log(v_b_f.toString()); 08 var v_null = null; 09 console.log(v_null.toString()); 10 </script>
关于【代码2-27】的分析如下:
第02行代码定义了第一个变量(v_str),并初始化赋值了字符串“toString()”;
第03行代码应用toString()函数方法将变量(v_str)转换为字符串,然后将返回的结果在浏览器控制台窗口中进行了输出。此处读者可能会有疑问,既然变量(v_str)已经初始化为字符串,还可以使用toString()函数方法再次转换为字符串类型吗?答案是肯定的,ECMAScript语法允许这样操作,因为String类型本身是原始类型,定义的变量还是伪对象,自然就支持toString()函数方法;
第04行代码定义了第二个变量(v_b_t),并初始化赋值Boolean类型的原始值(“true”);
第05行代码应用toString()函数方法将Boolean变量(v_b_t)转换为字符串,然后将返回的结果在浏览器控制台窗口中进行输出;
类似地,第06行代码定义了第三个变量(v_b_f),并初始化赋值Boolean类型的原始值(“false”);
第07行代码应用toString()函数方法将Boolean变量(v_b_f)转换为字符串,然后将返回的结果在浏览器控制台窗口中进行输出;
第08行代码定义了第四个变量(v_null),并初始化赋值Null类型的原始值(“null”);定义这行代码的目的是测试Null类型是否支持toString()函数方法的操作;
第09行代码应用toString()函数方法将Null类型变量(v_null)转换为字符串,然后将返回后的结果在浏览器控制台窗口中进行了输出。
页面效果如图2.27所示。第03行代码输出的结果表明对String类型变量应用toString()方法后返回的仍是原字符串的内容;第05行和第07行代码输出的结果表明对Boolean类型变量应用toString()方法后返回的是“true”或“false”原始值;第09行代码输出的结果表明,对Null类型变量应用toString()方法后会返回类型错误的提示信息。
图2.27 toString()函数方法(1)
下面,继续看第二个使用toString(argument)函数方法对Number类型数值进行转换成字符串操作的代码示例(详见源代码ch02目录中ch02-js-toString-b.html文件)。
【代码2-28】
01 <script type="text/javascript"> 02 var v_i_1 = 123; 03 console.log(v_i_1.toString()); 04 var v_i_2 = -123; 05 console.log(v_i_2.toString()); 06 var v_f_1 = 123.0; 07 console.log(v_f_1.toString()); 08 var v_f_2 = 123.123; 09 console.log(v_f_2.toString()); 10 var v_e = 123e8; 11 console.log(v_e.toString()); 12 </script>
页面效果如图2.28所示。通过以上代码输出的结果来看,Number类型的数值在应用toString()方法后返回的仍是表示原始值内容的字符串。
图2.28 toString()函数方法(2)
最后,我们看第三个使用带参数“argument”的toString(argument)函数方法对Number类型数值进行转换成字符串操作的代码示例(详见源代码ch02目录中ch02-js-toString-c.html文件)。
【代码2-29】
01 <script type="text/javascript"> 02 var v_i_2 = 11; 03 console.log(v_i_2.toString(2)); 04 var v_i_8 = 63; 05 console.log(v_i_8.toString(8)); 06 var v_i_16 = 255; 07 console.log(v_i_16.toString(16)); 08 </script>
页面效果如图2.29所示。第03行代码输出的结果表明十进制数值11对应的二进制数值正是1011;第05行代码输出的结果表明十进制数值63对应的八进制数值正是77;第07行代码输出的结果表明十进制数值255对应的十六进制数值正是ff。
另外,toString()函数方法默认参数为0,其实与toString(10)函数方法一致,只不过十进制参数10可以省略。
图2.29 toString()函数方法(3)
根据Ecma-262规范中的定义,ECMAScript语法提供了两个函数方法可以将非数字的原始值转换成数字,分别是parseInt()函数方法和parseFloat()函数方法。
其中,parseInt()方法用于将值转换成整数,parseFloat()方法用于将值转换成浮点数。另外,parseInt()方法和parseFloat()方法仅仅对String类型才有效,而对于其他类型返回的都是值NaN。
下面,先看第一使用parseInt()函数方法将值转换成数字操作的代码示例(详见源代码ch02目录中ch02-js-parseInt.html文件)。
【代码2-30】
01 <script type="text/javascript"> 02 var v_i = parseInt("123"); 03 console.log(v_i); 04 var v_f = parseInt("123.123"); 05 console.log(v_f); 06 var v_hex = parseInt("0x11ff"); 07 console.log(v_hex); 08 var v_i_str = parseInt("123abc"); 09 console.log(v_i_str); 10 var v_str = parseInt("abc123"); 11 console.log(v_str); 12 </script>
关于【代码2-30】的分析如下:
第02行代码定义了第一个变量(v_i),并初始化赋值为通过parseInt("123")方法将整数字符串转换成数字的返回值;
第04行代码定义了第二个变量(v_f),并初始化赋值为通过parseInt("123.123")方法将浮点数字符串转换成数字的返回值;
第06行代码定义了第三个变量(v_hex),并初始化赋值为通过parseInt("0x11ff")方法将十六进制字符串转换成数字的返回值;
第08行代码定义了第四个变量(v_i_str),并初始化赋值为通过parseInt("123abc")方法将字符串("123abc")转换成数字的返回值;
第10行代码定义了第四个变量(v_str_i),并初始化赋值为通过parseInt("abc123")方法将字符串("abc123")转换成数字的返回值。
页面的效果如图2.30所示。
图2.30 parseInt()函数方法(1)
从图中可以看到,第03行和第05行代码输出的结果相同,也就是说对于应用parseInt()方法进行转换的字符串如果包含Number类型数值,无论是整数或浮点数,返回的均是整数类型;因为parseInt()方法不能识别小数点(.),所以parseInt()方法会自动舍弃浮点数中小数点以后(包含小数点)的数值;
第07行代码输出的结果表明如果字符串定义成十六进制形式的字符串,parseInt()方法是能够识别出来并按照十六进制数值换算成十进制数值进行返回;
第09行代码输出的结果表明如果字符串定义成类似“123abc”字符串的形式,parseInt()方法能够识别出前面的数值,并将识别出来的数值进行返回。这是因为parseInt()方法是按照从前至后的顺序依次识别字符串中的字符的,一旦遇到字符串中的字符为非数字,就会马上终止执行,并将已经识别的数字(本例为123)进行返回;
第11行代码输出的结果表明如果字符串定义成类似“abc123”字符串的形式,parseInt()方法会认为是无效字符串,并会返回原始值NaN。
通过以上的代码可以看出parseInt()方法主要就是针对Number类型为数据,而对于其他类型的数据使用parseInt()方法是无效的。
下面,继续看第二个使用parseInt()函数方法将字符串转换成不同进制数字的代码示例(详见源代码ch02目录中ch02-js-parseInt-argument.html文件)。
【代码2-31】
01 <script type="text/javascript"> 02 var v_i_2 = 11; 03 console.log("parseInt(11, 2) = " + parseInt(v_i_2, 2)); 04 var v_i_8 = 77; 05 console.log("parseInt(77, 8) = " + parseInt(v_i_8, 8)); 06 var v_i_16 = "ff"; 07 console.log("parseInt(ff, 16) = " + parseInt(v_i_16, 16)); 08 </script>
页面效果如图2.31所示。使用带参数的parseInt()函数方法可以将目标值按照参数指定的进制数进行转换。另外,parseInt()函数方法默认参数为10,也就是说parseInt()方法默认就是将字符串转换成十进制数。
图2.31 parseInt()函数方法(2)
最后,看一个使用parseFloat()函数方法将字符串转换成浮点数字操作的代码示例(详见源代码ch02目录中ch02-js-parseFloat.html文件)。
【代码2-32】
01 <script type="text/javascript"> 02 var v_f_1= parseFloat("123.0"); 03 console.log('parseFloat("123.0") = ' + v_f_1); 04 var v_f_3 = parseFloat("123.123"); 05 console.log('parseFloat("123.123") = ' + v_f_3); 06 var v_f_f = parseFloat("123.123.123"); 07 console.log('parseFloat("123.123.123") = ' + v_f_f); 08 var v_f_oct = parseFloat("063"); 09 console.log('parseFloat("063") = ' + v_f_oct); 10 var v_f_hex = parseFloat("0x1f"); 11 console.log('parseFloat("0x1f") = ' + v_f_hex); 12 var v_f_str = parseFloat("123.abc"); 13 console.log('parseFloat("123.abc") = ' + v_f_str); 14 var v_str_f = parseFloat("abc.123"); 15 console.log('parseFloat("abc.123") = ' + v_str_f); 16 </script>
页面效果如图2.32所示。通过以上的代码可以看出,parseFloat()方法与parseInt()方法在识别字符的功能上是类似的,都是按照从前至后的顺序依次识别字符串中的字符,一旦遇到字符串中的字符为非数字(注意,parseFloat()方法会将第一个小数点认为是有效的),就会马上终止执行,并将已经识别的浮点数进行返回。
图2.32 parseFloat()函数方法
根据Ecma-262规范中的定义,ECMAScript语法还提供了强制类型转换(type casting)来处理转换值的类型,这一点与其他很多高级程序设计语言是类似的。ECMAScript语法规定,在使用强制类型转换时可以访问特定的值,即使其是另一种类型。
ECMAScript语法中定义了三种强制类型转换,具体如下:
另外,在使用这三个函数进行转换值操作时,将会创建一个新值,存放由原始值直接转换成的值。
下面,先看第一个使用Number()函数方法进行强制类型转换操作的代码示例(详见源代码ch02目录中ch02-js-number-cast.html文件)。
【代码2-33】
01 <script type="text/javascript"> 02 console.info("Number(123) = " + Number(123)); 03 console.info('Number("123") = ' + Number("123")); 04 console.info('Number("abc") = ' + Number("abc")); 05 console.info('Number(123.123) = ' + Number(123.123)); 06 console.info('Number("123.123") = ' + Number("123.123")); 07 console.info('Number("123.123.123") = ' + Number("123.123.123")); 08 console.info("Number(true) = " + Number(true)); 09 console.info("Number(false) = " + Number(false)); 10 console.info("Number(null) = " + Number(null)); 11 console.info("Number(undefined) = " + Number(undefined)); 12 </script>
关于【代码2-33】的分析如下:
第02行代码通过Number(123)方法将整数123强制转换成Number类型;
第03行代码通过Number("123")方法将字符串“123”强制转换成Number类型;
第04行代码通过Number("abc")方法将字符串“abc”强制转换成Number类型;
第05行代码通过Number(123.123)方法将浮点数123.123强制转换成Number类型;
第06行代码通过Number("123.123")方法将字符串“123.123”强制转换成Number类型;
第07行代码通过Number("123.123.123")方法将字符串“123.123.123”强制转换成Number类型;
第08~09行代码通过Number(true)方法和Number(false)方法将Boolean类型值强制转换成Number类型;
第10行代码通过Number(null)方法尝试将Null类型值强制转换成Number类型;
第11行代码通过Number(undefined)方法尝试将Undefined类型值强制转换成Number类型。
页面效果如图2.33所示。
图2.33 Number()强制类型转换
以上就是使用Number()方法对大部分类型进行强制类型转换的结果,读者在使用Number()方法时需要加以注意。
下面,继续看第二个使用Boolean()函数方法进行强制类型转换操作的代码示例(详见源代码ch02目录中ch02-js-boolean-cast.html文件)。
【代码2-34】
01 <script type="text/javascript"> 02 console.info("Boolean(true) = " + Boolean(true)); 03 console.info("Boolean(false) = " + Boolean(false)); 04 console.info("Boolean(1) = " + Boolean(1)); 05 console.info("Boolean(10) = " + Boolean(10)); 06 console.info("Boolean(0) = " + Boolean(0)); 07 console.info('Boolean("abc") = ' + Boolean("abc")); 08 console.info('Boolean("") = ' + Boolean("")); 09 console.info("Boolean(null) = " + Boolean(null)); 10 console.info("Boolean(undefined) = " + Boolean(undefined)); 11 </script>
页面效果如图2.34所示。
图2.34 Boolean()强制类型转换
以上就是使用Boolean()方法对部分类型进行强制类型转换的结果,读者在使用Boolean()方法时需要加以注意。
最后,看第三个使用String()函数方法进行强制类型转换操作的代码示例(详见源代码ch02目录中ch02-js-string-cast.html文件)。
【代码2-35】
01 <script type="text/javascript"> 02 var v_str_null = String(null); 03 console.info("String(null) = " + v_str_null); 04 var v_null = null; 05 console.info("null.toString() = " + v_null.toString()); 06 </script>
页面效果如图2.35所示。对null值使用String()方法进行强制类型转换时,可以正确生成字符串而不会引发错误;而对null值使用toString()方法进行操作时,则引发了类型错误。同样的,对于undefined值也会产生同样的结果,读者可自行将【代码2-35】中的null值替换为undefined值测试一下。
图2.35 String()强制类型转换
其实,String()强制类型转换方法是非常简单的,该方法可以将任何值转换成字符串。不过,还是建议使用toString()方法进行转换字符串的操作,除非必须使用【代码2-35】中大多数情况下第02行同样的代码。
对于本小节介绍的强制类型转换方法,在实际项目开发中是非常有用的;因为我们知道ECMAScript是弱类型的编程语言,在很多情况下都需要对变量进行强制类型转换操作,希望读者加以重视。