第2章 数据类型

本章将讲解JavaScript程序设计中的基本要素,即数据类型。任何一种程序设计语言,都离不开对数据和业务逻辑的处理,对数据进行操作前必须确定数据的类型。数据的类型规定了可以对该数据进行的操作和数据存储的方式。

JavaScript作为一门脚本语言,其使用过程完全表现出自动化特点。和其他脚本语言一样,使用时不需要显式指定数据的类型,仅在某些特殊场合才需要知道某一数据的类型。JavaScript数据类型包括基本类型和复合类型,本章重点讲解各种常用的数据类型。

● 理解和掌握基本数据类型的特点,以便在今后程序设计中正确运用

● 理解和掌握复合数据类型的特点,并通过实际的练习加以巩固

● 理解并掌握常用的内置对象的特性和使用方法

以上几点是对读者在学习本章内容时所提出的基本要求,也是本章希望能够达到的目的。读者在学习本章内容时可以将其作为学习的参照。

2.1 基本数据类型

每一种程序设计语言都规定了一套数据类型,其中最基本不可再细分的类型称为基本数据类型。JavaScript基本数据类型包括字符串型、布尔型和数值型等,这几种是JavaScript中使用最为普遍的数据类型,下面分别讲解各种类型的特点和使用方法。

2.1.1 字符串型数据

在JavaScript中,字符串型数据是用引号括起的文本字符串。例如“好久不见,你还好吗?”或‘Bob是个聪明的孩子’。每一个字符串数据都是String对象的实例,其主要用于组织处理由多个字符构成的数据串。定义一个字符串时不需要指定类型,只需要按以下语法定义即可。

定义字符串的第一种形式如下:

        var hello = "你好啊";

定义字符串的第二种形式如下:

        var hello = '你好啊';

其中,var是JavaScript中用于定义变量的关键字。此处用其定义一个名为hello的字符串变量,关于变量的内容将在本书第3章详细讲解。程序执行时系统自动为hello采用字符串的处理方式,此处字符串变量hello的数据内容为“你好啊”。第一种定义方式和第二种定义方式效果完全一样,系统不会对此加以区分,下面编写一个程序演示字符串用法。

【范例2-1】编写程序,练习使用引号定义字符串变量。向Peter输出一句问候语,如示例代码2-1所示。

示例代码2-1

        01  <script language="javascript">                  // 脚本程序开始
        02  <!--
        03       var hello = "你好啊";                       // 使用双引号定义字符串
        04       var name = 'Peter';                        // 使用单引号定义字符串
        05       alert(hello + name );                      // 将两个字符串合在一起显示
        06  -->
        07  </script>                                       <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,所得结果如图2-1所示。

【代码解析】本例代码中第3行和第4行分别使用双引号和单引号定义字符串变量,主要演示字符串变量的定义方法。第5行使用window对象的alert方法将连接后的字符串数据输出显示。

图2-1 连接后的字符串

2.1.2 深入理解字符串

在JavaScript中不区分“字符”和“字符串”,字符也被当做字符串处理。例如,在字符串“this is a string”中“h”是按从左到右顺序的第一个字符,可以使用字符串对象的charAt方法取出一个字符串中的指定的一个字符,有关“对象”的内容将在本书的后续章节讲到。

提示:字符串中的字符索引从0开始,所以上述字符串中的“h”是该串的第一个字符。字符串中的字符按顺序存储。

前面讲述的是有关字符串的定义方式。字符串中的字符数据仅包含常见的普通字符,然而字符串中可以包含用于特殊目的字符。比如用于换行控制的字符“\n”,此类字符在JavaScript中称为转义字符。转义字符的定义以“\”开始,JavaScript中的转义字符如表2-1所示。

表2-1 JavaScript中部分常用的转义字符

表2-1列出了一些常用的转义字符,更多的转义字符请查阅相关资料。一般来说转义字符主要用于在字符串中输入一些控制字符和系统已经保留了的字符,比如双引号、单引号和左斜杠等。下面通过编写程序演示转义字符的使用方法。

【范例2-2】编写程序,使用转义字符在字符串中输出回车换行、制表符和引号等。演示转义字符的使用方法,如示例代码2-2所示。

示例代码2-2

        01  <script language="javascript">             // 脚本程序开始
        02       var str1 = "1,使用回车换行符\n";         // 行尾使用"\n"作回车换行
        03       var str2 = "2,使用回车符\r";            // 行尾使用"\r"回车符
        04       var str3 = "3,使用:\t制表符\n";         // 行中间使用一个制表符"\t"
        05       var str4 = "4,使用\"双引号\"";          // 使用引号"\""
        06       var str  = str1 + str2 + str3 + str4;  // 将4个字符串连接为了一个串用于显示
        07       alert(str);                            // 在对话框是显示连接后的串str
        08  </script>                                  // 脚本程序结束

【运行结果】双击网页文件运行程序,其结果如图2-2所示。

图2-2 输出引号

【代码解析】第2行定义字符串变量str1并为其赋值,串末尾使用了“回车换行”转义字符“\n”,起到换行的作用。第3行定义字符串变量str2,串末尾使用“回车”转义字符“\r”,相当于输入字符串时按了一次回车键。第4行所定义的字符变量str3的值中使用了“制表符”转义字符“\t”,作用是在输出该字符串时将其当做一个“Tab”键处理。

第5行的字符串变量str4的值中使用了引号转义字符“\"”。因为引号已经被JavaScript保留为关键字符,所以用户在字符串中使用引号时采用转义字符“\"”即可。第6行将前面定义的4个字符串连接为一个字符串str,并用于以后输出显示。

提示:一部分转义字符在输出为HTML文本流时并不发生作用,比如制表符、回车换行等。读者不妨自行测试,将上述例子中的alert(str)换成document.write(str)后所得结果与图2-2相比较。

2.1.3 使用数值型数据

JavaScript中用于表示数字的类型称为数字型,不像其他编程语言那样区分整型、浮点型。数字型用双精度浮点值来表示数字数据,可以表示(-253,+253)区间中的任何值。数字的值可以用普通的记法也可以使用科学记数法。

JavaScript的数字可以写成十进制、十六进制和八进制,其各种写法如下:

● 十进制,可以用普通记法和科学记数法。

        10;                                        // 数字
        10.1;                                      // 数字
        0.1;                                       // 数字
        3e7;                                       // 科学记数
        0.3E7;                                     // 科学记数

● 十六进制以“0X”或“0x”开头后面跟0~F的十六进制数字,没有小数和指数部分。

        0xAF3E;                                    // 十六进制
        0X30FB;                                    // 十六进制

● 八进制以0开头,后跟0~7的八进制数字,同样没有小数和指数部分。

        037;                                       // 八进制
        012346;                                    // 八进制

以上是常用的数字表示法,下面通过编写程序来加深对数字型数据的理解。

【范例2-3】编写程序,练习八进制、十六进制、十进制数字的表示方法。演示JavaScript常用的数字型数据的使用方法,如示例代码2-3所示。

示例代码2-3

        01  <script language="javascript">         // 脚本程序开始
        02  <!--
        03                                         // 使用16进制数
        04       var i = 0Xa1;                      // 分别定义两个数字变量,并使用0x和
                                                  // 0X作十六进制设置初值
        05       var j = 0xf2;
        06       var s = i + j;                     // 十六进制变量i与j相加
        07                                         // 输出为十进制
        08       document.write("<li>十六进制数0xa1等于十进制数:" + i + "<br>" );
        09       document.write("<li>十六进制数0xf2等于十进制数:" + j + "<br>" );
        10       document.write("<li>十六进制数0xf2加上0xa1的和为:" + s + "<br>" );
        11
        12                                         // 使用8进制数
        13       var k = 0123;                      // 分别定义两个数值变量,分别用八进制值
                                                  // 设置为初值
        14       var l = 071;
        15       var m = k + l;                     // 两个变量的值相加
        16                                         // 输出为十进制
        17       document.write("<li>八进制数0123等于十进制数:" + k + "<br>" );
        18       document.write("<li>八进制数071等于十进制数:" + l + "<br>" );
        19       document.write("<li>八进制数0123加上071的和为:" + m + "<br>" );
        20                                         // 使用10进制
        21       var t1 = 0.1;                      // 定义十进制小数数字的形式
        22       var t2 = 1.1;
        23       var t3 = 2e3;                      // 使用科学计数法表示数值
        24       var t4 = 2e-3
        25       var t5 = 0.1e2;
        26       var t6 = 0.1e-2;                   // 将各变量的值全部输出
        27       document.write("<li>十进制带小数的形式:" + t1 + "和" + t2 + "<br>" );
                                                  // 在文档中输出变量
        28       document.write("<li>十进制科学记数2e3等于:" + t3 + "<br>" );
                                                  // 在文档中输出变量
        29       document.write("<li>十进制科学记数2e-3等于:" + t4 + "<br>" );
                                                  // 在文档中输出变量
        30       document.write("<li>十进制科学记数0.1e2等于:" + t5 + "<br>" );
                                                  // 在文档中输出变量
        31       document.write("<li>十进制科学记数0.1e-2等于:" + t6 + "<br>" );
                                                  // 在文档中输出变量
        32  -->
        33  </script>                              // 脚本程序开始

【运行结果】双击网页文件运行程序,其结果如图2-3所示。

图2-3 各种进制数混合运算

【代码解析】本示例第4~6行定义三个变量,并分别赋十六进制表示的初值。第8~10行将三个变量输出为十进制表示的数。第13~15行定义三个变量,分别赋八进制表示的初值。第17~19行将三个变量输出为十进制表示的数。第21~26行定义数个变量并对它们赋予用不同表示法表示的十进制数值。第27~31行将变量t1~t6逐一输出为普通的十进制数字。

提示:用科学记数法、十六进制记数法和八进制记数法表示的数字,在输出时全部自动转换为普通的十进制形式。

2.1.4 使用布尔型数据

布尔型是只有“真”和“假”两个值的数据类型。作为逻辑表达式的结果,真值用“true”表示,假值用“false”表示。事实上,非0值即为“真”,0值即为“假”。布尔型数据通常用来表示某个条件是否成立,定义的一个布尔型变量的形式如下:

        var b = true                           // 布尔型变量

或者如下:

        var b = false;                         // 布尔型变量

提示:在JavaScript中定义任何变量都不需要显式地为其指定类型,系统会根据变量的值类型来确定变量的数据类型。上述变量b的值为true或false时,系统会确定该变量的数据类型为布尔型。

下面编写程序演示布尔数据类型的使用方法。

【范例2-4】编写程序,练习布尔型数据的使用方法。验证“非零值为真,零值为假”,掌握布尔型数据的特点,如示例代码2-4所示。

示例代码2-4

        01  <script language="javascript">             // 脚本程序
        02  <!--
        03       var b1 = true;                         // 定义布尔型变量b1并赋初始为“真”
        04       if( b1 )                               //判断b1的真是否为真,真则执行“{}”
                                                      // 中的语句
        05       {
        06           document.write("变量b1的值为\"真\"<br>");
                                                      // 输出提示
        07       }
        08       var b2 = false;                        // 定义布尔变量
        09       if( b2 )                               // 为真时
        10       {
        11           document.write("变量b2的值为\"真\"<br>");
                                                      // 输出提示
        12       }
        13       else                                   // 为假时
        14       {
        15           document.write("变量b2的值为\"假\"<br>");
                                                      // 输出提示
        16       }
        17       var b3 = 0.1;                          // 定义数字类型变量b3并赋予非0值
        18       if( b3 )                               // 此处b3被当做布尔型变量,若为真
        19       {
        20           document.write("变量b3的值为\"真\"<br>");
                                                      // 输出提示
        21       }
        22       var b4 = -1;                           // 定义数字类型变量b4并赋予非0值
        23       if( b4 )                               // 此处b4被当做布尔型变量,若为真
        24       {
        25           document.write("变量b4的值为\"真\"<br>");
                                                      // 输出提示
        26       }
        27       var b5 = 0;                            // 定义数字类型变量并赋予0值
        28       if( b5 )                               // 此处b5被当做布尔型变量,若为真
        29       {
        30           document.write("变量b5的值为\"真\"<br>");
                                                      // 输出提示
        31       }
        32       else                                   // 为假时
        33       {
        34           document.write("变量b5的值为\"假\"<br>");
                                                      // 输出提示
        35       }
        36  -->
        37  </script>                                  // 脚本程序结束

【运行结果】打开网页文件运行程序,其结果如图2-4所示。

【代码解析】本示例使用了if语句对布尔型变量的值进行判断,关于if语句将在后面的章节讲到。此处读者只需知道如果if后小括号里布尔型变量的值为真时,则执行if后“{}”中的语句。

图2-4 非零值为真

第3行定义一个布尔型变量并为其赋予初值true,在第4行中将其作为if控制语句的测试条件。其值为“真”,于是执行第5~7行“{}”中的内容。第18行和第23行分别将非0数字型变量当做布尔型变量使用,作为if控制语句的测试条件。结果表明,非0值的数字型变量作为布尔型变量使用时,其值为“真”。第27~35行使用了一个0值数字型变量b5作布尔型变量使用,结果表明其布尔值为“假”。

提示:JavaScript中除了“true”和“false”表示“真”和“假”外,任意非0值就表示“真”,0值表示“假”,请读者多做测试。

2.2 复合数据类型

前面一节所讲的字符串型、数值型和布尔型数据是JavaScript的简单数据类型。本节将介绍复合数据类型,对象和数组。对象是JavaScript封装了一套操作方法和属性的类实例,是基本数据类型之一。本书后面的章节将安排专门的内容来介绍数组。

2.2.1 常用内置对象

在面向对象的设计模式中,将数据和处理数据的方法捆绑在一起形成一个整体,称为对象。换句话说,对象封装了数据和操作数据的方法,要使用其中的数据或方法须先创建该对象。可以使用new运算符来调用对象的构造函数,从而创建一个对象,方式如下:

        var obj = new Object();                    // 创建新对象

参数说明:

● obj,变量名,必需。指向创建的Object对象。

要访问已经创建对象的属性或方法,可以使用“.”运算符,形式如下:

        obj.toString();                            // 作为字符串输出

上述代码调用对象obj的toString方法。

JavaScript内建了几种常用的对象,封装了常用的方法和属性,如表2-2所示。

表2-2 JavaScript中常用的对象

下面对表2-2中常用的对象进行讲解,包括Date、String、Global、Number和Math,其他对象在后面的章节有专门的内容讲解。

2.2.2 常用日期对象

JavaScript将与日期相关的所有特性封装进Date对象,包括日期信息及其操作,主要用来进行与时间相关的操作。Data对象一个典型应用是获取当前系统时间,使用前首先创建该对象的一个实例,创建语法如下:

        date = new Date( );                                 // 直接创建
        date = new Date( val );                             // 指定日期创建
        date = new Date( y , m, d [, h [, min [, sec [,ms]]]] );
                                                          // 指定日期创建

参数说明:

● val,必选项。表示指定日期与1970年1月1日午夜间全球标准时间的毫秒数。

● y、m和d分别对应年、月和日,必选。h、min、sec和ms分别对应时、分、秒和毫秒,可选。

这三种创建方式中根据需要选择一种即可。第一种方式创建一个包含创建时时间值的Date对象。第二种方式创建一个与1970年1月1日午夜间全球标准时间相差val毫秒的日期。第三种方式创建指定年、月、日、时、分、秒和毫秒的日期。

【范例2-5】编写程序,显示程序运行时的本地时间。演示Date对象的使用方法,如示例代码2-5所示。

示例代码2-5

        01  <script language="javascript">                      // 脚本程序开始
        02  <!--
        03       var cur = new Date();                           // 创建当前日期对象cur
        04       var years = cur.getYear();                      //从日期对象cur中取得年数
        05       var months = cur.getMonth();                    // 取得月数
        06       var days = cur.getDate();                       // 取得天数
        07       var hours = cur.getHours();                     // 取得小时数
        08       var minutes = cur.getMinutes();                 // 取得分钟数
        09       var seconds = cur.getSeconds();                 // 取得秒数
        10                                                      // 显示取得的各个时间值
        11       alert( "此时时间是:" + years + "年" + (months+1) + "月"
                                                                // 输出日期信息
        12           + days + "日" + hours + "时" + minutes + "分"
        13           + seconds + "秒" );
        14  -->
        15  </script>                                           <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,其结果如图2-5所示。

【代码解析】本示例使用Date对象取得当前日期。第4行调用Date对象的默认构造函数Date创建一个对象,Date对象的默认构造函数将创建带有当前时间信息的Date对象。若要创建带有指定时间信息的Date对象,请使用带参数的构造函数,或者创建后调用Date对象的方法设定时间。第8~18行分别使用Date对象的get系列方法取得相关值,第20行组合显示各变量的值。

图2-5 输出当前时间

Date对象提供了大量用于日期操作的方法和属性,下面归纳Date对象的部分常用方法,如表2-3所示。

表2-3 Date对象的常用方法

表2-3中get系列是获取时间值的方法,set系列是设置时间值的方法,下面通过编写程序加以巩固。

【范例2-6】编写程序,创建一个Date对象,将其中日期设置为2007年4月20日。练习设置Date对象中时间值,如示例代码2-6所示。

示例代码2-6

        01  <script language="javascript">                      // 脚本程序开始
        02  <!--
        03       var dateObj = new Date();                       // 创建一个日期对象
        04       dateObj.setYear( 2007 );                        // 设置日期对象的年份
        05       dateObj.setDate( 20 );                          // 设置日期对象的日期
        06       dateObj.setMonth( 4 );                          // 设置日期对象的月份
        07                                                      // 显示日期对象中的时间
        08       alert( "dateObj中设定的时间为:" + dateObj.getYear() + "年"
                                                                // 输出日期信息
        09           + dateObj.getMonth() + "月" + dateObj.getDate() + "日" );
        10  -->
        11  </script>                                           <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,其结果如图2-6所示。

【代码解析】第3~10行创建一个日期对象并使用其set系列方法设置各个时间值。第08行调用日期对象的get系列方法取出的各个时间值,并在对话框中显示出来。

图2-6 Date对象中的日期

2.2.3 理解全局对象

全局对象是所有全局方法的拥有者,用来统一管理全局方法,全局方法也就是指全局函数。该对象不能使用new运算符创建对象实例,所有方法直接调用即可。以下是几个常用的Global对象的方法,如表2-4所示。

表2-4 Global对象的常用方法

【范例2-7】编写程序,调用Global对象的isNaN方法判断一个值是否为数值,如示例代码2-7所示。

示例代码2-7

        01  <script language="javascript">                  // 脚本程序开始
        02  <!--
        03       var a = NaN;                               // 定义非数字常量
        04       var b = "123";                             // 字符串样式数字
        05       var c = 123;                               // 数字变量
        06       var d = "1.23";                            // 字符串样式数字
        07       document.write( "<b>Global对象的isNaN方法</b><br>" );
                                                          // 输出标题
        08       var ta =  isNaN( a );                       // 用isNaN方法测试a的值
        09       document.write( "<li>a的值是否是NaN:" + ta + "<br>" );
                                                          // 输出提示
        10       var tb = isNaN( b );                       // 测试b的值
        11       document.write( "<li>b的值是否是NaN:" + tb + "<br>" );
                                                          // 输出提示
        12       var tc = isNaN( c );                       // 测试c的值
        13       document.write( "<li>c的值是否是NaN:" + tc + "<br>" );
                                                          // 输出提示
        14       document.write( "<b>Global对象的parseInt方法</b><br>" ); // 输出提示
        15       var ib = parseInt( b );                    //将字符串“123”解析为数值123
        16       if( ib == c )                              // 如果相等
        17       {
        18           document.write( "<li>b解析为数值:" + ib + "<br>" );
                                                          // 输出标题
        19       }
        20       document.write( "<b>Global对象的parseFloat方法</b><br>" );
                                                          //输出标题
        21       var id = parseFloat( d );                  //将字符串“1.23”解析为数值1.23
        22       if( id == 1.23 )                           // 如果相等
        23       {
        24           document.write( "<li>b解析为数值:" + id + "<br>" );
                                                          // 输出提示
        25       }
        26  -->
        27  </script>                                       <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,其结果如图2-7所示。

图2-7 字符串转换为数字

【代码解析】本示例演示Global对象的isNaN、parseInt和parseFloat三个方法的使用方式。Global对象无须创建即可直接使用,因此使用其方法时也无须使用“obj.方法名”的形式。第3~6行定义一组用于测试前述三个Global方法的变量。第8行使用isNaN方法测试变量a是否为NaN值,此处返回一个为“true”的布尔值。第15和21行分别使用parseInt和parseFloat方法将字符串解析为数字。

注意:parseFloat方法不解析以非数字字符开头的字符串,数字字符后的字符被忽略。读者可以将示例代码2-7中的“var d = "1.23";”改成类似“var d = "1.23char";”的形式即可测试。

2.2.4 常用数学对象

数学对象(Math)封装了与数学相关的特性,包括一些常数和数学函数,主要使用简单一些基本的数学计算。该对象和Global对象一样不能使用new运算符创建,Math对象在程序运行时由JavaScript环境创建并初始化。调用Math对象的方法或属性的方式如下:

Math.[ {属性名|方法名} ];

下面列出了Math对象部分常用的方法和属性,供查阅之用,如表2-5所示。

表2-5 Math对象常用的方法和属性

通过表2-5可以看出,Math对象的很多方法在很大程度上简化了基本的数学运算。比如求正弦、余弦、对数等,下面编写程序以熟悉Math对象的使用方法。

【范例2-8】从Math对象中获取圆周率常数,计算一个半径为2单位的圆的面积,如示例代码2-8所示。

示例代码2-8

        01  <script language="javascript">             // 脚本程序开始
        02  <!--
        03       var r = 2;                             // 定义变量表示半径
        04       var pi = Math.PI;                      // 从Math对象中读取周期率PI常量
        05       var s = pi*r*r;                        // 计算面积
        06       alert("半径为2单位的圆面积为:" + s + "单位" );
                                                      // 显示圆的面积
        07  -->
        08  </script>                                  <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,其结果如图2-8所示。

图2-8 圆的面积

【代码解析】第3行定义一个值为2的变量r作为圆的半径,第4行读取Math对象的PI属性,并存于变量pi中。第8~10行根据圆面积求解公式计算出面积s并输出显示。

注意:Math对象的方法和属性直接调而不需要创建Math对象,否则出错。

【范例2-9】调用Math对象的sin方法求90度角的正弦值,调用abs方法求数的绝对值。如示例代码2-9所示。

示例代码2-9

        01  <script language="javascript">                          // 脚本程序开始
        02  <!--
        03       var r1 = Math.sin( Math.PI/2 );                     // 求正弦
        04       document.write("<li>弧度为pi/2的正弦值为:" + r1 + "<br>" );
                                                                    // 输出提示
        05       var r2 = 0-r1;                                      // 取反
        06       var r3 = Math.abs( r2 );                            // 求绝对值
        07       document.write("<li>" + r2 + "的绝对值为:" + r3 + "<br>" );
                                                                    // 输出提示
        08  -->
        09  </script>                                               <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,其结果如图2-9所示。

图2-9 常量PI使用弧度单位

【代码解析】代码第04行调用Math的sin方法计算PI/2的正弦值,结果保存到变量r1中。第08行调用Math对象的abs方法求值为负数的r2的绝对值。本程序演示了Math对象方法的调用方式,读者可以结合表2-3对Math对象的常用方法多加练习。

注意:Math对象的sin等方法需要输入用弧度度量的角度值参数。

2.2.5 常用字符串对象

String对象封装了与字符串有关的特性,主要用来处理字符串。通过String对象,可以对字符串进行剪切、合并、替换等操作。可以调用该对象的构造函数创建一个实例,其实在定义一个字符串类型变量时也就创建了一个String对象实例。调用String对象的方法或属性形式如“对象名.方法名”或“对象名.属性名”,其构造函数如下:

        String([strVal]);

参数strVal是一个字符串,可选项。创建一个包含值为strVal的String对象。

String对象的方法比较多,涵盖了字符串处理的各个方面,读者可根据需要查阅相关参考手册。下面通过举例演示String对象的使用方法。

【范例2-10】在文本串中将李白《静夜思》的各个部分分别提取出来,并格式化输出。标题加粗,文本居中对齐,诗歌正文颜色为灰色。如示例代码2-10所示。

示例代码2-10

        01  <script language="javascript">                  // 脚本程序开始
        02  <!--
        03       var comment = "静夜思李白床前明月光,疑是地上霜。举头望明月,低头思故乡。";
                                                          // 诗的内容
        04       var partial = comment.substring( 0, 3 );   // 取出标题
        05       partial = partial.bold();          // 标题加粗
        06       document.write( "<p align=\"center\">" );
                                                  // 输出HTML标签“<p>”,并设置居中对齐
        07       document.write( partial );         // 输出标题
        08       partial = comment.slice( 3, 5 );   // 取出作者
        09       document.write( "<br>" );          // 输出换行标签<br>
        10       document.write( partial );         // 输出作者
        11       partial = comment.slice( 5, 17 );  // 取出第一句诗文
        12       partial = partial.fontcolor("gray");   // 设置颜色为gray(灰色)
        13       document.write( "<br>" );              // 输出换行标签
        14       document.write( partial );             // 输出诗句
        15       partial = comment.slice( 17, 29 );     // 取出第二句诗文
        16       partial = partial.fontcolor("gray");   // 设置颜色为gray(灰色)
        17       document.write( "<br>" );              // 输出换行标签
        18       document.write( partial );             // 输出诗句
        19       document.write( "</p>" );              // 输出HTML标签“<p>”的结束标签
        20  -->
        21  </script>                                  <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,其结果如图2-10所示。

图2-10 格化式输出

【代码解析】本示例演示了String对象的使用方法。第3行创建一个String对象comment,其内容为诗歌文本。第4~19行分别从comment对象中提取相应的内容,设置为目标格式后输出。其中设置加粗、颜色等方法操作的最终结果是在目标文本中应该HTML标签。

String对象的其他方法还有很多,限于篇幅在此只讲部分常用的,更多信息请读者查阅相关资料。本节主要介绍了Object、Global、Date、String和Math对象,JavaScript其他内建对象将在后面的章节再做讲解。

2.2.6 掌握数组对象

数组是JavaScript中另一种重要的基本数据类型。内部对象Array封装了所有和数组相关的方法和属性,其内部存在多个数据段组合存储。可以形象地将其理解为一种有很多连续房间的楼层,每个房间都可以存放货物,提取货物时只需要给出楼层号和房间编号即可,如图2-11所示。

图2-11 数组式的房间序列

● 创建数组的方式1,直接使用new运算符调用Array对象的构造函数,代码如下所示。

        var a = new Array();                            // 创建数组

以上代码创建一个没有任何元素的数组a。

● 创建数组的方式2,给构造函数传递数组元素为参数,代码如下所示。

        var a = new Array(10, 20, 30, "string", 40 );   // 创建带指定元素的数组

给构造函数传递的元素参数可以是任何JavaScript数据类型,JavaScript数组各元素的类型可以不相同。上述代码创建了一个5个元素的数组a。

● 创建数组的方式3,不调用构造函数,直接将元素放入“[]”中即可,元素间用“,”分隔。

        var a = [ 10, 20, 30, "string", 40 ];           // 创建数组

上述代码将创建一个具有5个元素的数组a,效果与方式2完全相同。

● 创建数组的方式4,给构造函数传递数组元素个数可以创建具有指定元素个数的数组。

        var a = new Array(3);                           // 指定长度创建数组

上述代码创建了一个有3个元素的数组a。数组元素的下标从0开始,使用“数组名[下标]”的方式访问数组元素。下面编程演示数组的创建和使用。

【范例2-11】创建一个数组用于保存古代几个大诗人的名字,通过遍历数组逐一输出每个诗人的名字,如示例代码2-11所示。

示例代码2-11

        01  <script language="javascript">                          // 脚本程序开始
        02  <!--
        03       var poets = new Array( "王维",  "杜甫", "李白", "白居易" );
                                                                    // 创建数组
        04       document.write("古代几个大诗人:<br>");                // 输出标题
        05       for( n in poets )                                   // 逐个输出数组元素
        06       {
        07           document.write( "<li>" + poets[n] );            // 输出诗人的名字
        08       }
        09  -->
        10  </script>                                               <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,结果如图2-12所示。

图2-12 遍历数组

【代码解析】本示例演示了创建数组的简单形式,通过“[]”运算符可以读取数组元素的内容。第3行创建诗人名字数组,第5~8行逐一将数组中的每个名字作为一个项目输出到页面文本中。

提示:创建数组时尽管已经指定了元素个数,但真正为元素分配内存须等到给元素赋值的时候。

本节让读者对数组有一个大致印象,本书第7章将对数组做专门的讲解。

2.3 其他数据类型

前面介绍了简单数据类型、复合数据类型。JavaScript是基于对象的语言,带有部分面向对象的特性,因此“对象”是一种用户自定义数据类型。JavaScript用户自定义对象使用形式非常简单,只需要定义对象的构造函数即可。通过在构造函数中为对象添加属性和方法,从而形成新的数据类型。最终,函数在JavaScript中被视为一种数据类型。本节将讲解函数的初级内容和其他一些数据类型,例如null、undefined等。

2.3.1 使用函数

在JavaScript中,“函数”充当了两个角色,一个运用在数据类型方面,另一个运用在子程序设计方面。此前与“对象”有关的东西随处可见,然而JavaScript却没有使用类的概念。在此函数用来定义一种数据类型,可以认为是用户自定义数据类型。本书后面将安排专门的章节来讲解函数和面向对象的内容。

定义一种自定义数据类型的方法如下面代码所示。

        function TypeName([arg,…])
        {
            this.arg = arg;
        }

上述代码使用“function”关键字定义了数据类型“TypeName”,其构造函数带可选参数“arg”。下面通过编程演示自定义数据类型的使用。

【范例2-12】编写程序,定义一种数据类型表示汽车,包含“车主”、“极速”两种属性。如示例代码2-12所示。

示例代码2-12

        01  <script language="javascript">                      // 脚本程序开始
        02  <!--
        03       function Card( owner, rate )                    // 定义车子对象
        04       {
        05           this.Owner = owner;                        // 车主
        06           this.MaxRate = rate;                       // 极速
        07       }
        08       var myCard = new Card( "Sunsir", "400KMpH" );   // 创建一个车子实例
        09       document.write( myCard.Owner + "的车子极速为" + myCard.MaxRate );
                                                                // 输出车子的属性
        10  -->
        11  </script>                                           <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,结果如图2-13所示。

图2-13 程序运行结果

【代码解析】第3~5行使用关键字function定义了一个自定义数据类型Card,该类型包含两个属性字段。第8、9行创建一个Card对象实例,并将其属性值输出在HTML文本流中。

提示:函数的字段可以任意指定,也可以任意添加方法。

2.3.2 使用空值

前面所讲过的每一种JavaScript数据类型都有自己的内容,而编程中却需要一种类型来表示“什么都没有”。null类型就是为此目的而产生,其表示一个空值。可以使用null和一个变量进行比较以测试该变量是否拥有内容,通常用来判断对象的创建或引用是否成功。

【范例2-13】编写程序,测试null值,如示例代码2-13所示。

示例代码2-13

        01  <script language="javascript">     // 脚本程序开始
        02  <!--
        03       var x = 10;                   // 定义变量x,并给其赋值10
        04       var y = null;                 // 定义变量y,并赋一个空值,表示“什么都没有”
        05       if( x == null )               // 如果x为空值则
        06       {
        07           document.write( "x的值为空<br>" );
                                              // 输出提示
        08       }
        09       if( y == null )               // 如果y为空则
        10       {
        11           document.write( "y的值为空<br>" );
                                              // 输出提示
        12       }
        13  -->
        14  </script>                          <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,结果如图2-14所示。

【代码解析】第3行定义一个数字型变量x并赋值10,使x拥有一个为10的数值。第4行定义一个变量y并为其赋一个null值,使y不拥有任何值。第5~12行分别测试x和y是否为空,若为空则输出文字以表示。

图2-14 y为null

提示:当创建一个对象失败时,通常返回一个null值,此时可以通过测试返回值是否为null而确定对象创建是否成功。

2.3.3 使用不确定的类型

null值表示一个变量拥有空值。可以理解为已经把“空”赋给了某个变量,而undefined则表示一个变量什么都没有得到,连“空”都没有。通常用来判断一个变量是否已经定义或已经赋值,下面编程测试这两者的区别。

【范例2-14】编写程序,测试undefined值,如示例代码2-14所示。

示例代码2-14

        01  <script language="javascript">         // 脚本程序开始
        02  <!--
        03       var v0 = 1;                        // 定义一个值为1的变量
        04       var v1 = null;                     // 定义一个变量,并指定值为null
        05       var v2;                            // 定义一个变量,但不赋任何值
        06       document.write("变量v0的内容为:" + v0 + "<br>" );
                                                  // 输出v0
        07       document.write("变量v1的内容为:" + v1 + "<br>" );
                                                  // 输出v1
        08       document.write("变量v2的内容为:" + v2 + "<br>" );
                                                  // 输出v2
        09       if( v1 == v2 )                     // 测试“null”和“undefined”的相等性
        10       {
        11           document.write("\"null\"和\"undefined\"相等<br>" );
                                                  // 输出提示
        12       }
        13       else                               // 不相等
        14       {
        15           document.write("\"null\"和\"undefined\"不相等<br>" );
                                                  // 输出提示
        16       }
        17  -->
        18  </script>                              <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,其结果如图2-15所示。

【代码解析】第3行定义变量v0并为其赋值1,使其拥有一个数字类型的值。第4行定义变量v1变赋值null。第5行声明一个变量v2,但不赋任何值。第6~8行分别输出变量v0、v1和v2的内容。第9行判断null和undefined是否相等,结果为相等。

图2-15 区别null与undefined

提示:在应用中null和undefined实际意义是等效的。

2.4 数据类型的转换

JavaScript是一门简单的、弱类型的编程语言。使用时无须指定数据类型,系统会根据值的类型进行变量类型自动匹配,或者根据需要自动在类型间进行转换。JavaScript类型转换包括隐式类型转换和显式类型转换两种。

2.4.1 隐式类型转换

程序运行时,系统根据当前上下文的需要,自动将数据从一种类型转换为另一种类型的过程称为隐式类型转换。此前的代码中,大量使用了window对象的alert方法和document对象的write方法。可以向这两个方法中传入任何类型的数据,这些数据最终都被自动转换为字符串型。

【范例2-15】编写程序,收集用户的年龄数据。当用户输入的数字小于等于零时发出警告,外部输入的数据都是字符串型,与数字作比较判断时系统自动将其转换为数值型。如示例代码2-15所示。

示例代码2-15

        01  <script language="javascript">             // 脚本程序开始
        02  <!--
        03       var age = prompt("请输入您的年龄:", "0");// 输入年龄
        04       if( age <= 0 )                         // 如果输入的数字小于等于0则视为非法
        05       {
        06           alert("您输入的数据不合法!");        // 输入非法时警告并忽略
        07       }
        08       else                                   // 大于
        09       {
        10           alert( "你的年龄为" + age + "岁" );  // 输出年龄
        11       }
        12  -->
        13  </script>                                  <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,结果如图2-16、图2-17所示。

图2-16 数字转换为字符串

图2-17 输出用户输入的数据

【代码解析】第3行用户输入的数据以字符串的形式保存于变量age中。第4行将age与数字0做大小比较,此时age自动被转换为数值型,此过程称为隐式类型转换。第5~11行根据age的值是否符合要求而显示相应的信息。

2.4.2 显式类型转换

与隐式类型转换相对应的是显式类型转换,此过程需要手动转换到目标类型。要将某一类型的数据转换为另一类型的数据需要用到特定的方法。比如前面用到的parseInt、parseFloat等方法,下面再编写一个范例以演示这两个方法的使用。

【范例2-16】编写程序,从字符串中解析出水果价格的数值数据。如果解析成功则输出价格信息,如示例代码2-16所示。

示例代码2-16

        01  <script language="javascript">                      // 脚本程序开始
        02  <!--
        03       var priceOfApple = "3元";                       // 苹果的价格
        04       var priceOfBanana = "3.5元";                    // 香蕉的价格
        05       priceOfApple = parseInt( priceOfApple );        // 解析苹果的价格
        06       var priceOfBanana2 = parseInt( priceOfBanana ); // 解析香蕉的价格
        07       if( ( priceOfApple===3 ) && ( priceOfBanana2 === 3 )
                                                                // 检查解析是否成功
        08         && ( parseFloat( priceOfBanana ) ===3.5 ) )
        09       {
        10           alert( "苹果的价格:" + priceOfApple          // 输出水果的价格
        11               + "\n香蕉的价格的整数部分:" + priceOfBanana2
        12               + "\n香蕉的价格:" + parseFloat( priceOfBanana ) );
        13       }
        14       else                                            // 解析失败时
        15       {
        16           alert( "并没有得到预期的转换效果!" );          // 解析失败时输出警告信息
        17       }
        18  -->
        19  </script>                                           <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,结果如图2-18所示。

【代码解析】本示例主要演示显式类型转换,第3、4行设置两个字符串表示两种水果的价格。第5、6行将字符串解析为数字,得到水果价格的数值数据。第7~17行判断所解析出的价格数据是否正确,正确时将它们输出,否则输出警告。

图2-18 数字与字符串间的转换

提示:当要转换的字符串带有parseInt或parseFloat方法不可识别的字符时,转换结果可能没法预料。读者可自行做这方面的测试。

2.5 小结

本章主要讲解了简单数据类型,其包括字符串型、数值型和布尔型。复合数据类型包括对象和数组,对象是JavaScript中最重要的数据类型之一。本章仅涉及系统内置的对象,包括Global、Math、Date、Array、Number等。各种基本的数据类型之间可以相互转换,根据转换的方式分为隐式和显式两种。数据类型是程序设计语言最基本的要素之一,希望读者认真理解掌握。如果读者对本章内容还有什么疑问,可以参考《JavaScript实例自学手册:通过486个例子掌握Web开发捷径》(电子工业出版社,吴雪)和《JavaScript权威指南》(机械工业出版社)等书籍。

2.6 习题

一、常见面试题

1.JavaScript是否有专门对字符和字符串的处理?

【解析】本题具有一定的迷惑性,如果熟悉一些高级开发语言,应聘者可能知道高级语言是区分字符和字符串的处理的。而JavaScript语言并不区分,这一点读者一定注意。

2.数据库有空值吗?JavaScript是否也有空值?

【解析】本题考查对基础知识的了解,JavaScript中的null类型表示一个空值。可以使用null和一个变量进行比较以测试该变量是否拥有内容,通常用来判断对象的创建或引用是否成功。

二、简答题

1.JavaScript的基本数据类型有哪些?

2.写出几种常用的内置对象。

3.什么是数组?它与基本的数据类型有什么关系?

三、综合练习

1.编写一个程序,记录学生的《高等数学》成绩。要求集中输出位于60~69、70~79、80~89和90~100各个分数段的学生名字。

【提示】该题可以用一个数组记录学生名字和分数,偶数元素保存学生的名字,奇数元素存储学生的成绩。遍历数组时检查元素索引的奇偶性即可分辨当前元素是名字还是分数。得到分数值后判断其所在分数阶段,其前一个数组元素即为得到该分数的学生名字。将各分数段的学生名字分别添加到相应的变量,最后一并输出,参考代码如下:

        01  <script language="javascript">                  // 脚本程序开始
        02  <!--
        03       var score = new Array(    "王勇", 50,       // 分数表
        04                    "白露", 60,
        05                    "杨杨", 76,
        06                    "李明", 83,
        07                    "张莉莉", 70,
        08                    "杨宗楠", 71,
        09                    "徐霞", 66,
        10                    "杨玉婷", 93
        11                   );
        12       var namesOf_0To59 = "";                    // 0~59分的学生名字串
        13       var namesOf_60To69 = "";                   // 60~69分的学生名字串
        14       var namesOf_70To79 = "";                   // 70~79分的学生名字串
        15       var namesOf_80To89 = "";                   // 80~89分的学生名字串
        16       var namesOf_90To100 = "";                  // 90~100分的学生名字串
        17       var scoreSum = 0;                          // 全体总分计数
        18       document.write( "<b>《高等数学》成绩统计表</b><br>" );
                                                          // 标题
        19       for( index in score )                      // 遍历分数数组
        20       {
        21           // 奇数索引元素为分数,其前一个元素即为该分数的学生名字
        22           if( index%2==1 )                       // 分数
        23           {
        24               // 判断当前分数所在的分数段并将学生名字存入相应变量
        25               if( (score[index]>=0) && (score[index]<=59) )
                                                          // 如果在分数在0~59分间
        26               {
        27                    namesOf_0To59 += score[index-1] + " ";
                                                          // 组合名字
        28               }
        29               if( (score[index]>=60) && (score[index]<=69) )
                                                          // 如果在分数在60~69分间
        30               {
        31                    namesOf_60To69 += score[index-1] + " ";
                                                          // 组合名字
        32               }
        33               if( (score[index]>=70) && (score[index]<=79) )
                                                          // 如果在分数在70~79分间
        34               {
        35                    namesOf_70To79 += score[index-1] + " ";
                                                          // 组合名字
        36               }
        37               if( (score[index]>=80) && (score[index]<=89) )
                                                          // 如果在分数在80~89分间
        38               {
        39                    namesOf_80To89 += score[index-1] + " ";
                                                          // 组合名字
        40               }
        41               if( (score[index]>=90) && (score[index]<=100) )
                                                          // 如果在分数在90~100分间
        42               {
        43                    namesOf_90To100 += score[index-1] + " ";
                                                          // 组合名字
        44               }
        45               scoreSum += score[index];          // 统计总分
        46           }
        47       }
        48       document.write( "<li>00~59分:" + namesOf_0To59 + "<br>" );
                                                          // 输出0~59分的学生名字
        49       document.write( "<li>60~69分:" + namesOf_60To69 + "<br>" );
                                                          // 输出60~69分的学生名字
        50       document.write( "<li>70~79分:" + namesOf_70To79 + "<br>" );
                                                          // 输出70~79分的学生名字
        51       document.write( "<li>80~89分:" + namesOf_80To89 + "<br>" );
                                                          // 输出80~89分的学生名字
        52       document.write( "<li>90~100分:" + namesOf_90To100 + "<br>" );
                                                          // 输出90~100分的学生名字
        53       // 数组元素个数除以2即为人数,总分除以人数即得平均分
        54       document.write( "<li>平均分 :" + scoreSum/(score.length/2) + "<br>" );
        55  -->
        56  </script>                                       <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,结果如图2-19所示。

2.朱自清《荷塘月色》中有文段“采莲南塘秋,莲花过人头;低头弄莲子,莲子清如水。今晚若有采莲人,这儿的莲花也算得‘过人头’了;只不见一些流水的影子,是不行的。这令我到底惦着江南了”。现编写程序,将文中的“莲”字加粗、用红色标记之。

图2-19 运行结果

【提示】使用String对象来处理题中的短文。多次调用charAt方法获取文本中的每一个字符,判断所取字符如果是“莲”字就调用bold方法和fontcolor方法对其设置粗体和颜色。参考代码如下:

        01  <script language="javascript">                      // 脚本程序开始
        02  <!--
        03       var comment = "采莲南塘秋,莲花过人头;低头弄莲子,莲子清如水。
                                                                // 选文
        04  今晚若有采莲人,这儿的莲花也算得“过人头”了;只不见一些流水的影子,
        05  是不行的。这令我到底惦着江南了。"
        06       var newComment = "";                            // 处理过的字符集合
        07       for( n = 0; n<comment.length; n ++ )            // 处理选文中的每一个字符
        08       {
        09           var curChar = comment.charAt( n );         // 取得一个字符
        10           if( curChar=="莲" )                         // 若为“莲”字时
        11           {
        12               newComment += (curChar.bold()).fontcolor("red");
                                                                // 加粗并设置红色
        13           }
        14           else                                       // 非“莲”字
        15           {
        16               newComment += curChar;                 // 直接添加到已处理内容
        17           }
        18       }
        19       document.write("<li><b>原文:</b><br>" + comment + "<br>" );
                                                                // 输出原文
        20       document.write("<li><b>标记“莲”字:</b><br>" + newComment + "<br>" );
                                                                // 输出新内容
        21  -->
        22  </script>                                           <!--脚本程序结束-->

【运行结果】打开网页文件运行程序,其结果如图2-20所示。

图2-20 运行结果

四、编程题

1.写一个程序输出当前时间。

【提示】可以考虑使用时间函数。

2.写一个程序求一个数的平方根。

【提示】利用数学函数中的平方根函数即可轻松实现。