《JavaScript从零开始学:视频教学版》试读:对象是JavaScript最基本的数据类型之一,将多种数据类型集中在一个数据单元中,同时允许通过对象名来存取这些数据的值。数组是JavaScript中唯一用来存储和操作有序数据集的数据结构。本章主要介绍对象与数组的基本概念和基础知识。
5.1 了解对象
在JavaScript中,对象包括内置对象、自定义对象等多种类型,使用这些对象可大大简化JavaScript程序的设计,并以提供直观、模块化的方式进行脚本程序开发。
5.1.1 什么是对象
对象(Object)是一件事、一个实体、一个名词,可以获得的东西,可以想象有标识的任何东西。对象是类的实例化。一些对象是活的,一些对象不是。若以自然人为例,构造一个对象,其中Attribute表示对象状态,Method表示对象行为,如图5-1所示。
图5-1 对象状态和行为
在计算机语言中也存在对象,可以定义为相关变量和方法的软件集。对象主要由下面两部分组成:
一组包含各种类型数据的属性。
允许对属性中的数据进行操作且有相关方法。
以HTML文档中的document对象为例,其中包含各种方法和属性,如图5-2所示。
图5-2 以HTML文档中的document为例构造的对象
凡是能够提取一定度量数据,并能通过某种方式对度量数据实施操作的客观存在都可以构成一个对象。同时可以用属性来描述对象的状态、使用方法和事件来处理对象的各种行为。
属性:用来描述对象的状态,通过定义属性值来定义对象的状态。如图5-1所示,可以定义字符串Nationality来表示人的国籍,所以Nationality成为人的某个属性。
方法:针对对象行为的复杂性,对象的某些行为可以用通用的代码来处理,这些代码就是方法。如图5-2所示,可以定义方法Open()来处理文件的打开情况,此时Open()就成为方法。
事件:由于对象行为的复杂性,对象的某些行为不能使用通用的代码来处理,需要用户根据实际情况来编写处理该行为的代码,该代码称为事件。
JavaScript是基于对象的编程语言,除循环和关系运算符等语言构造之外,其所有的特征几乎都是按照对象的处理方法进行的。
JavaScript支持的对象主要包括以下4种。
JavaScript核心对象:包括同基本数据类型相关的对象(如String、Boolean、Number)、允许创建用户自定义和组合类型的对象(如Object、Array)和其他能简化JavaScript操作的对象(如Math、Date、RegExp、Function)。
浏览器对象:包括不属于JavaScript语言本身但被绝大多数浏览器所支持的对象,如控制浏览器窗口和用户交互界面的window对象、提供客户端浏览器配置信息的Navigator对象。
用户自定义对象:Web应用程序开发者用于完成特定任务而创建的自定义对象,可自由设计对象的属性、方法和事件处理程序,编程灵活性较大。
文本对象:由文本域构成的对象,在DOM中定义,同时赋予很多特定的处理方法,如insertData()、appendData()等。
5.1.2 面向对象编程
面向对象程序设计(Object-Oriented Programming,OOP)是一种起源于上个世纪60年代的Simula语言,其自身理论已经十分完善,并被多种面向对象程序设计语言实现。面向对象编程的基本原则是:计算机程序由单个能够起到子程序作用的单元或对象组合而成。具有三个最基本的特点:重用性、灵活性和扩展性。这种方法将软件程序中的每一个元素作为一个对象看待,同时定义对象的类型、属性和描述对象的方法。为了实现整体操作,每个对象都应该能够接收信息、处理数据和向其他对象发送信息。
面向对象编程主要包含如下三个重要的概念。
1.继承
继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础上进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。继承性是面向对象程序设计语言不同于其他语言的最重要的特点,也是其他语言所没有的。
继承主要分为以下两种类型:
在类层次中,子类只继承一个父类的数据结构和方法,称为单重继承。
在类层次中,子类继承了多个父类的数据结构和方法,称为多重继承。
在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类行之有效的方法,简化了对象、类的创建工作量,增加了代码的可重用性。采用继承性,提供了类规范的等级结构。通过类的继承关系,使公共的特性能够共享,提高了软件的重用性。
2.封装
封装的作用是将对象的实现过程通过函数等方式封装起来,使用户只能通过对象提供的属性、方法和事件等接口去访问对象,而不需要知道对象的具体实现过程。封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是通过外部接口——特定的访问权限来使用类的成员。
封装允许对象运行的代码相对于调用者来说是完全独立的,调用者通过对象及相关接口参数来访问此接口。只要对象的接口不变,而只是对象的内部结构或实现方法发生了改变,程序的其他部分不用作任何处理。
3.多态
多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。多态性允许每个对象以适合自身的方式去响应共同的消息。多态性增强了软件的灵活性和重用性。
需要说明的是:定位JavaScript脚本是基于对象的脚本编程语言,而不是面向对象和编程语言。其原因在于:JavaScript是以DOM和BOM中定义的对象模型及操作方法为基础的,但又不具备面向对象编程语言所必须具备的显著特征,如分类、继承、封装、多态、重载等,所以只能通过嵌入其他面向对象编程语言如Java生成的JavaApplet组件等来实现相应的功能。另外,JavaScript还支持DOM和BOM提供的对象模型,用于根据其对象模型的层次结构来访问目标对象的属性并对对象施加相应的操作。
在JavaScript语言中,之所以任何类型的对象都可以赋予任意类型的数值,是因为JavaScript为弱类型的脚本语言,即变量在使用前无须任何声明,在浏览器解释运行其代码时,才检查目标变量的数据类型。
5.1.3 JavaScript的内部对象
JavaScript的内部对象按照使用方式可以分为静态对象和动态对象两种。在引用动态对象的属性和方法时,必须使用new关键字来创建一个对象实例,然后才能使用“对象实例名.成员”的方式来访问其属性和方法;在引用静态对象属性和方法时,不需要使用new关键字来创建对象实例,直接使用“对象名.成员”的方式来访问其属性和方法即可。
JavaScript中常见内部对象如表5-1所示。
表5-1 JavaScript内部对象
对象名 功能 静态/动态性
Object对象 使用该对象可以在程序运行时为JavaScript对象随意添加属性 动态对象
String对象 用于处理或格式化文本字符串以及确定和定位字符串中的子字符串 动态对象
Date对象 使用Date对象执行各种日期和时间的操作 动态对象
Event对象 用来表示JavaScript的事件 静态对象
FileSystemObiect对象 主要用于实现文件操作功能 动态对象
Drive对象 主要用于收集系统中的物理或逻辑驱动器资源中的内容 动态对象
File对象 用于获取服务器端指定文件的相关属性 静态对象
Folder对象 用于获取服务器端指定文件的相关属性 静态对象
5.2 对象访问语句
在JavaScript中,用于对象访问的语句有两种,分别是for…in循环语句和with语句。下面详细介绍这两种语句的用法。
5.2.1 for…in循环语句
for…in循环语句和for语句十分相似,该语句用来遍历对象的每一个属性。每次都会将属性名作为字符串保存在变量中。
for…in语句的语法格式如下:
for(variable in object){
…statement
}
其中参数说明如下。
variable:该参数是一个变量名,声明一个变量的var语句、数组的一个元素或者对象的一个属性。
object:该参数是一个对象名,或者是计算结果为对象的表达式。
statement:该参数通常是一个原始语句或者语句块,由它构建循环的主体。
【例5.1】(实例文件:ch05\5.1.html)for…in语句的使用。
<!DOCTYPE>
<head>
<title>使用for in语句</title>
</head>
<body>
<script type="text/javascript">
var myarray = new Array()
myarray[0] = "星期一"
myarray[1] = "星期二"
myarray[2] = "星期三"
myarray[3] = "星期四"
myarray[4] = "星期五"
myarray[5] = "星期六"
myarray[6] = "星期日"
for (var i in myarray)
{
document.write(myarray[i] + "<br />")
}
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-3所示。
图5-3 程序运行结果
5.2.2 with语句
有了with语句,在存取对象属性和方法时就不用重复指定参考对象了,在with语句块中,凡是JavaScript不识别的属性和方法都和该语句块指定的对象有关。
with语句的语法格式如下:
with object {
statements
}
对象指明了当语句组中对象缺省时的参考对象,这里用较为熟悉的document对象对with语句举例。例如,当使用与document对象有关的write()或writeln()方法时,往往使用如下形式:
document.writeln("Hello!")
如果需要显示大量数据时,就会多次使用同样的document.writeln()语句,这时就可以像下面的程序那样,把所有以document对象为参考对象的语句放到with语句块中,从而达到减少语句量的目的。
【例5.2】(实例文件:ch05\5.2.html)with语句的使用。
<!DOCTYPE>
<html>
<head>
<title>with语句的使用</title>
</head>
<body>
<script type ="text/javascript">
var date_time=new Date();
with(date_time){
var a=getMonth()+1;
alert(getFullYear()+"年"+a+"月"+getDate()+"日"+getHours()+":"+getMinutes()+":"+getSeconds());
}
var date_time=new Date();
alert(date_time.getFullYear()+"年"+date_time.getMonth()+1+"月"+date_time.getDate()+"日"+date_time.
getHours()+":"+date_time.getMinutes()+":"+date_time.getSeconds());
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-4所示。
图5-4 程序运行结果
5.3 JavaScript中的数组
数组是有序数据的集合,JavaScript中的数组元素允许属于不同的数据类型。用数组名和下标可以确定数组中唯一的元素。
5.3.1 结构化数据
在JavaScript程序中,Array(数组)被定义为有序的数据集。最好将数组想像成一个表,与电子数据表很类似。在JavaScript中,数组被限制为一个只有一列数据的表,但却有许多行,用来容纳所有的数据。JavaScript浏览器为HTML文档和浏览器属性中的对象创建了许多内部数组。例如,如果文档中含有5个链接,则浏览器就保留一张链接的表。
可以通过数组语法中的编号(0是第一个链接)访问它们:数组名后紧跟着的是方括号中的索引数。例如Document.links[0],代表着文档中的第一个链接。在许多JavaScript应用程序中,可以利用与表单元素的交互作用,使用数组来组织网页使用者所访问的数据。
对于许多JavaScript应用程序来说,可以将数组作为有组织的数据仓库来使用,这些数据是页面的浏览者基于他们与表单元素交互而访问的数据。数组是JavaScript增强页面重新创建服务器端复制CCI程序行为的一种方式。当嵌在脚本中的数据集与典型的.gif文件一样大的时候,用户在载入页面时不会感觉有很长的时间延迟,然而还有充分的权力对小数据库集进行即时查询,而不需要对服务器进行任何回调。这种面向数据库的数组是JavaScript的一个重要应用,称为serverlessCGIs(无服务器CGI)。
如果有许多对象或者数据点使用同样的方式与脚本进行交互,那么就可以使用数组结构。例如,除IE 3外,在每一个浏览器中,可以在一个订货表单中为每列的文本域指定类似的名称,这里,类似名称的对象可以作为数组元素处理。为了重复处理订货表单的行计算,脚本可以在很少的JavaScript语句中使用数组语法来完成,而不是对每个域都用代码编写许多语句。
还可以创建类似Java哈希表的数组:哈希表是一个查找表,如果知道与表目有关联的名称,就能立刻找到想要的数据点,如果认为数据是一个表的形式,就可以使用数组。
5.3.2 创建和访问数组对象
数组是具有相同数据类型的变量集合,这些变量都可以通过索引进行访问。数组中的变量称为数组的元素,数组能够容纳元素的数量称为数组的长度。数组中的每个元素都具有唯一的索引(或称为下标)与其相对应,在JavaScript中数组的索引从零开始。
Array对象是常用的内置动作脚本对象,它将数据存储在已编号的属性中,而不是已命名的属性中。数组元素的名称叫做索引。数组用于存储和检索特定类型的信息,例如学生列表或游戏中的一系列移动。Array对象类似String和Date对象,需要使用new关键字和构造函数来创建。
可以在创建一个Array对象时初始化它。
myArray=new Array()
myArray=new Array([size])
myArray=new Array([element0[,element1[,...[, elementN]]]])
其中各个参数的含义如下。
size:可选,指定一个整数表示数组的大小。
element0,...,elementN:可选,为要放到数组中的元素。创建数组后,能够用“[]”符号访问数组的单个元素。
由上述内容可知,创建数组对象有三种方法。
(1)新建一个长度为零的数组
var 数组名=new Array( );
例如,声明数组为myArr1,长度为0,代码如下:
var myArr1=new Array();
(2)新建长度为n的数组
var 数组名=new Array( n );
例如,声明数组为myArr2,长度为6,代码如下:
var myArr2=new Array(6);
(3)新建指定长度的数组,并赋值
var 数组名=new Array(元素1,元素2,元素3,…);
例如,声明数组为myArr3,并且分别赋值为1,2,3,4,代码如下:
var myArr3=new Array(1,2,3,4);
上面这一行代码,创建一个数组myArr3,并且包含4个元素myArr3[0]、myArr3[1]、myArr3[2]、myArr3[3],这4个元素值分别为1,2,3,4。
下列代码构造一个长度为5的数组,为其添加元素后,使用for循环语句枚举其元素。
【例5.3】(实例文件:ch05\5.3.html)
<!DOCTYPE HTML>
<html>
<head>
<script language=JavaScript>
myArray=new Array(5);
myArray[0]="a";
myArray[1]="b";
myArray[2]="c";
myArray[3]="d";
myArray[4]="e";
for (i = 0; i < 5; i++){
document.write(myArray[i]+"<br>");
}
</script>
<META content="MSHTML 6.00.2900.5726" name=GENERATOR>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-5所示。
图5-5 显示构造的数组
只要构造了一个数组,就可以使用中括号“[]”,通过索引和位置(它也是基于0的)来访问它的元素。每个数组对象实体也可以看作是一个对象,因为每个数组都是由它所包含的若干个数组元素组成的,每个数组元素都可以看作是这个数组对象的一个属性。可以用表示数组元素位置的数字来标识,也就是说数组对象使用数组元素的下标来进行区分,数组元素的下标从零开始索引,第一个下标为0,后面依次加1。访问数据的语法格式如下:
document.write(mycars[0])
下面的实例就是一个使用方括号访问并直接构造数组的实例。
【例5.4】(实例文件:ch05\5.4.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script language=JavaScript>
myArray=[["a1","b1","c1"],["a2","b2","c2"],["a3","b3","c3"]];
for (var i=0; i <= 2; i++){
document.write( myArray[i])
document.write("<br>");
}
document.write("<hr>");
for (i=0;i<3;i++){
for (j=0;j<3;j++){
document.write(myArray[i][j]+" ");
}
document.write("<br>");
}
</script>
<META content="MSHTML 6.00.2900.5726" name=GENERATOR>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-6所示。
图5-6 访问构造的数组
5.3.3 使用for…in语句
在JavaScript中可以使用for…in语句来控制循环输出数组中的元素,而不需要事先知道对象属性的个数。具体的语法格式为for (key in myArray),其中myArray表示数组名。
下面通过一个实例来介绍for…in语句的具体用法。
【例5.5】(实例文件:ch05\5.5.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script language=JavaScript>
myArray=new Array(5);
myArray[0]="a";
myArray[1]="b";
myArray[2]="c";
myArray[3]="d";
myArray[4]="e";
for (key in myArray){
document.write(myArray[key]+"<br>");
}
</script>
<META content="MSHTML 6.00.2900.5726" name=GENERATOR>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-7所示。
图5-7 循环输出数组中的数据
5.3.4 Array对象的常用属性和方法
JavaScript提供了一个Array内部对象来创建数组,通过调用Array对象的各种方法,可以方便地对数组进行排序、删除、合并等操作。
1.Array对象常用的属性
Array对象的属性主要有两个,分别是length属性和prototype属性,下面详细介绍这两个属性。
(1)length属性
该属性的作用是指定数组中元素数量的非从零开始的整数,当将新元素添加到数组时,此属性会自动更新。其语法格式为:my_array.length。
下面的实例解释length 属性是如何自动更新的。
【例5.6】(实例文件:ch05\5.6.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script language=JavaScript>
my_array = new Array();
document.write(my_array.length+"<br>"); // 初始长度为 0
my_array[0] = 'a';
document.write(my_array.length+"<br>"); // 将长度更新为1
my_array[1] = 'b';
document.write(my_array.length+"<br>"); //将长度更新为2
my_array[9] = 'c';
document.write(my_array.length+"<br>"); //将长度更新为10
</script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-8所示。
图5-8 给数组指定相应的整数
(2)prototype属性
该属性是所有JavaScript对象所共有的属性,和Date对象的prototype属性一样,其作用为将新定义的属性或方法添加到Array对象中,该对象的实例就可以调用该属性或方法。其语法格式为:
Array.prototype.methodName=functionName
其中各个参数说明作用如下。
methodName:必选项,新增方法的名称。
functionName:必选项,要添加到对象中的函数名称。
下面的实例是为Array对象添加返回数组中最大元素值的方法。必须声明该函数,并将它加入 Array.prototype中,且使用它。
【例5.7】(实例文件:ch05\5.7.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script>
//添加一个属性,用于统计删除的元素个数
Array.prototype.removed=0;
//添加一个方法,用于删除指定索引的元素
Array.prototype.removeAt=function(index)
{
if(isNaN(index)||index<0)
{return false;}
if(index>=this.length)
{index=this.length-1}
for(var i=index;i<this.length;i++)
{
this[i]=this[i+1];
}
this.length-=1
this.removed++;
}
//添加一个方法,输出数组中的全部数据
Array.prototype.outPut=function(sp)
{
for(var i=0;i<this.length;i++)
{
document.write(this[i]);
document.write(sp);
}
document.write("<br>");
}
//定义数组
var arr=new Array(1,2,3,4,5,6,7,8,9);
//测试添加的方法和属性
arr.outPut(" ");
document.write("删除一个数据<br>");
arr.removeAt(2);
arr.outPut(" ");
arr.removeAt(4);
document.write("删除一个数据<br>");
arr.outPut(" ")
document.write("一共删除了"+arr.removed+"个数据");
</script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-9所示。
图5-9 删除数组中的数据
这段代码利用prototype属性分别向Array对象中添加了两个方法和一个属性,分别实现了删除指定索引处的元素、输出数组中的所有元素和统计删除元素个数的功能。
2.Array对象常用的方法
Array对象常用的方法有连接方法concat、分隔方法join、追加方法push、倒转方法reverse、切片方法slice等。
(1)concat
该方法的作用是把当前数组和指定的数组相连接,返回一个新的数组,该数组中含有前面两个数组的全部元素,其长度为两个数组的长度之和。其基本的语法格式为:array1.concat (array2),其中参数说明如下。
array1:为必选项,数组名称。
array2:为必选项,数组名称,该数组中的元素将被添加到数组array1中。
下面的实例定义了两个数组array1和array2,然后把这两个数组连接并将值赋给数组array。
【例5.8】(实例文件:ch05\5.8.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script language=JavaScript>
var array1=new Array(1,2,3,4,5,6);
var array2=new Array(7,8,9,10);
var array=array1.concat(array2);
//自定义函数,输出数组中所有数据
function writeArr(arrname,sp)
{
for(var i=0;i<arrname.length;i++)
{
document.write(arrname[i]);
document.write(sp);
}
document.write("<br>");
}
document.write("数组1:");
writeArr(array1,",");
document.write("数组2:");
writeArr(array2,",");
document.write("数组3:");
writeArr(array,",");
</script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-10所示。
图5-10 链接数组
(2)join
该方法与String对象的split方法的作用相反,该方法的作用是将数组中所有元素连接为一个字符串,如果数组中的元素不是字符串,则该元素将首先被转化为字符串,各个元素之间可以以指定的分隔符进行连接。其语法格式为:array.join(separator),其中array为必选项,是数组的名称, separator也为必选项,是连接各个元素之间的分隔符。
下面的实例对比了split方法和join方法。
【例5.9】(实例文件:ch05\5.9.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script language=JavaScript>
var str1="this ia a test";
var arr=str1.split(" ");
var str2=arr.join(",");
with(document){
write(str1);
write("<br>分割为数组,数组长度"+arr.length+",重新连接如下:<br>");
write(str2);
}
</script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-11所示。
图5-11 将数组中所有元素连接为一个字符串
上面代码首先使用split方法以“”(空格)为分隔符将字符串分割存储到数组中,再调用join方法以“,”(逗号)为分隔符,将数组中的各个元素重新连接为一个新字符串。
(3)push
该方法可以将所指定的一个或多个数据添加到数组中,该方法的返回值为添加新数据后数组的长度。其语法格式为:array.push([data1[,data2[,…[,datan]]]]),其中参数的作用如下。
array:为必选项,数组名称。
data1、data2、datan:为可选参数,将被添加到数组中的数据。
下面的实例演示了如何利用push方法向数组中添加新数据。
【例5.10】(实例文件:ch05\5.10.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script language=JavaScript>
var arr=new Array();
document.write("向数组中写入数据:"); //单个数据写入数组
for (var i=1;i<=5;i++)
{
var data=arr.push(Math.ceil(Math.random()*10));
document.write(data);
document.write("个,");
}
document.write("<br>");//批量写入数组
var data=arr.push("a",4.15,"hello");
document.write("批量写入,数组长度已为"+data+"<br>");
var newarr=new Array(1,2,3,4,5);
document.write("向数组中写入另一个数组<br>"); //写入新数组
arr.push(newarr);
document.write("全部数据如下:<br>");
document.write(arr.join(","));
</script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-12所示。上面代码分别使用push方法,向数组中逐个和批量添加数据。
图5-12 使用push方法向数组添加数据
(4)reverse
该方法可以将数组中的元素反序排列,数组中所包含的内容和数组的长度不会改变。其语法格式为:array.reverse(),其中array为数组的名称。
下面就是将数组中的元素反序排列的实例。
【例5.11】(实例文件:ch05\5.11.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<script>
var arr=new Array(1,2,3,4,5,6);
with (document)
{
write("数组为:");
write(arr.join(","));
arr.reverse();
write("<br>反序后的数组为:")
write(arr.join("-"));
}
</script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-13所示。
图5-13 将数组中的元素反序排列
(5)slice
该方法将提取数组中的一个片段或子字符串,并将其作为新数组返回,而不修改原始数组。返回的数组包括 start 元素到 end 元素(但不包括该元素)的所有元素。
其语法格式为:my_array.slice( [ start [ , end ] ] ),其中各个参数的含义如下。
start:指定片段起始点索引的数字。
end:指定片段终点索引的数字。如果省略此参数,则片段包括数组中从开头start到结尾的所有元素。
下面的实例就是将数组中的一个片段或子字符串提取出来,并将其作为新数组返回,而不修改原始数组。
【例5.12】(实例文件:ch05\5.12.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<Script language="JavaScript">
var myArray = [1, 2, 3, 4, 5, 6,7];
newArray = myArray.slice(1, 6);
document.write(newArray);
document.write("<br>");
newArray = myArray.slice(1);
document.write(newArray);
</Script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-14所示。
图5-14 将其作为新数组返回
(6)sort
该方法对数组中的所有元素按Unicode编码进行排序,并返回经过排序后的数组。sort方法默认按升序进行排列,但也可以通过指定对比函数来实现特殊的排序要求,对比函数的格式为:comparefunction(arg1,arg2)。其中,comparefunction为排序函数的名称,该函数必须包含两个参数arg1和arg2,分别代表了两个将要进行对比的字符。该函数的返回值决定了如何对arg1和arg2进行排序。如果返回值为负,则arg2将排在arg1的后面;若返回值为0,arg1、arg2视为相等;若返回值为正,则arg2将排在arg1的前面。
sort方法的语法格式为:array.sort([cmpfun(arg1,arg2)]),参数说明如下。
array:为必选项,数组名称。
cmpfun:为可选项,比较函数。
arg1,arg2:为可选项,比较函数的两个参数。
下列实例演示了如何使用sort方法对数组中的数据进行排序。
【例5.13】(实例文件:ch05\5.13.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<Script language="JavaScript">
var arr=new Array(1,6,3,40,1,"a","b","A","B");
writeArr("排序前",arr);
writeArr("升序排列",arr.sort());
writeArr("降序排列,字母不分大小写",arr.sort(desc));
writeArr("严格降序排列",arr.sort(desc1));
//自定义函数输出提示信息和数组元素
function writeArr(str,array)
{
document.write(str+":");
document.write(array.join(","));
document.write("<br>");
}
//按降序排列,字母不区分大小写
function desc(a,b)
{
var a=new String(a);
var b=new String(b);
//如果a大于b,则返回-1,所以a排在前b排在后
return -1*a.localeCompare(b) ;
}
//严格降序
function desc1(a,b)
{
var stra=new String(a);
var strb=new String(b);
var ai=stra.charCodeAt(0);
var bi=strb.charCodeAt(0);
if( ai>bi )
return -1;
else
return 1;
}
</script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-15所示。这段代码中定义了两个对比函数,其中desc进行降序排列,但字母不区分大小写;desc1进行严格降序排列。
图5-15 对数组进行排序
(7)splice
该方法可以通过指定起始索引和数据个数的方式,删除或替换数组中的部分数据,该方法的返回值为被删除或替换掉的数据。其语法格式为:array.splice(start,count[,data1[,data2,[,…[,datacount]]]]),其中,array(必选项,数组名称);start(必选项,整数,起始索引);count(必选项,整数,要删除或替换的数组个数);data(可选项,用于替换指定数据的新数据)。
如果没有指定data参数,则该指定的数据将被删除;如果指定了data参数,则数组中的数据将被替换。下面通过一个实例介绍该方法的具体使用过程。
【例5.14】(实例文件:ch05\5.14.html)
<!DOCTYPE HTML>
<html>
<head>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<Script language="JavaScript">
var arr=new Array(0,1,2,3,4,5,6,7,8,9,10);
var rewith=new Array("a","b","c");
var tmp1=arr.splice(2,5,rewith);
with(document)
{
writeArr("替换了5个数据",tmp1);
writeArr("替换为:",rewith);
writeArr("替换后",arr);
var tmp2=arr.splice(5,2);
writeArr("删除2个数据",tmp2);
writeArr("替换后",arr); }
//自定义函数输出提示信息和数组元素
function writeArr(str,array)
{
document.write(str+":");
document.write(array.join(","));
document.write("<br>");
}
</script>
</head>
<body>
</body>
</html>
在IE 9.0中的浏览效果如图5-16所示。上面的代码分别演示了如何使用splice方法替换和删除数组中指定数目的数据。
图5-16 替换和删除数组中指定数目的数据
5.4 详解常用的数组对象方法
在JavaScript当中,数据对象的方法有14种,下面详细介绍常用的数组对象方法的使用。
5.4.1 连接其他数组到当前数组
使用concat()方法可以连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
语法格式如下:
arrayObject.concat(array1,array2,......,arrayN)
其中arrayN是必选项,该参数可以是具体的值,可以是数组对象,也可以是任意多个。
【例5.15】(实例文件:ch05\5.15.html)使用concat()方法连接三个数组。
<html>
<body>
<script type="text/javascript">
var arr = new Array(3)
arr[0] = "北京"
arr[1] = "上海"
arr[2] = "广州"
var arr2 = new Array(3)
arr2[0] = "西安"
arr2[1] = "天津"
arr2[2] = "杭州"
var arr3 = new Array(2)
arr3[0] = "长沙"
arr3[1] = "温州"
document.write(arr.concat(arr2,arr3))
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-17所示。
图5-17 程序运行结果
5.4.2 将数组元素连接为字符串
使用join()方法可以把数组中的所有元素放入一个字符串中。语法格式如下:
arrayObject.join(separator)
其中separator为可选项。用于指定要使用的分隔符,如果省略该参数,则使用逗号作为分隔符。
【例5.16】(实例文件:ch05\5.16.html)使用join()方法将数组元素连接为字符串。
<html>
<body>
<script type="text/javascript">
var arr = new Array(3);
arr[0] = "河北"
arr[1] = "石家庄"
arr[2] = "廊坊"
document.write(arr.join());
document.write("<br />");
document.write(arr.join("."));
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-18所示。
图5-18 程序运行结果
5.4.3 移除数组中最后一个元素
使用pop()方法可以移除并返回数组中最后一个元素,语法格式如下:
arrayObject.pop()
pop()方法将移除arrayObject的最后一个元素,把数组长度减1,并且返回它移除的元素的值。如果数组已经为空,则pop()不改变数组,并返回undefined值。
【例5.17】(实例文件:ch05\5.17.html)使用pop ()方法移除数组最后一个元素。
<html>
<html>
<body>
<script type="text/javascript">
var arr = new Array(3)
arr[0] = "河南"
arr[1] = "郑州"
arr[2] = "洛阳"
document.write("数组中原有元素:"+arr)
document.write("<br />")
document.write("被移除的元素:"+arr.pop())
document.write("<br />")
document.write("移除元素后的数组元素:"+arr)
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-19所示。
图5-19 程序运行结果
5.4.4 将指定的数值添加到数组中
使用push()方法可向数组的末尾添加一个或多个元素,并返回新的长度,语法格式如下:
arrayObject.push(newelement1,newelement2,....,newelementN)
其中,arrayObject为必选项,该参数为数组对象。newelement1为可选项,表示添加到数组中的元素。
push()方法可把它的参数顺序添加到arrayObject的尾部。它直接修改arrayObject,而不是创建一个新的数组。push()方法和pop()方法使用数组提供的先进后出的功能。
【例5.18】(实例文件:ch05\5.18.html)使用push ()方法将指定数值添加到数组中。
<html>
<body>
<script type="text/javascript">
var arr = new Array(3)
arr[0] = "河南"
arr[1] = "河北"
arr[2] = "江苏"
document.write("原有的数组元素:"+arr)
document.write("<br />")
document.write("添加元素后数组的长度:" +arr.push("吉林"))
document.write("<br />")
document.write("添加数值后的数组:" +arr)
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-20所示。
图5-20 程序运行结果
5.4.5 反序排列数组中的元素
使用reverse()方法可以颠倒数组中元素的顺序,语法格式如下:
arrayObject.reverse()
该方法会改变原来的数组,而不会创建新的数组。
【例5.19】(实例文件:ch05\5.19.html)使用reverse ()方法颠倒数组中的元素顺序。
<html>
<body>
<script type="text/javascript">
var arr = new Array(3)
arr[0] = "张三"
arr[1] = "李四"
arr[2] = "王五"
document.write(arr + "<br />")
document.write(arr.reverse())
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-21所示。
图5-21 程序运行结果
5.4.6 删除数组中的第一个元素
使用shift()方法可以把数组的第一个元素从其中删除,并返回第一个元素的值,语法格式如下:
arrayObject.shift()
其中,arrayObject为必选项,是数组对象。
如果数组是空的,那么shift()方法将不进行任何操作,并返回undefined值。请注意,该方法不创建新数组,而是直接修改原有的arrayObject。
【例5.20】(实例文件:ch05\5.20.html)使用shift ()方法删除数组中的第一个元素。
<html>
<body>
<script type="text/javascript">
var arr = new Array(4)
arr[0] = "北京"
arr[1] = "上海"
arr[2] = "广州"
arr[3] = "天津"
document.write("原有数组元素为:"+arr)
document.write("<br />")
document.write("删除数组中的第一个元素为:"+arr.shift())
document.write("<br />")
document.write("删除元素后的数组为:"+arr)
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-22所示。
图5-22 程序运行结果
5.4.7 获取数组中的一部分数据
使用slice()方法可从已有的数组中返回选定的元素,语法格式如下:
arrayObject.slice(start,end)
其中,arrayObject为必选项,是数组对象;start为必选项,表示开始元素的位置,是从0开始计算的索引。end为可选项,表示结束元素的位置,也是从0开始计算的索引。
【例5.21】(实例文件:ch05\5.21.html)使用slice ()方法获取数据中的一部分数据。
<html>
<body>
<script type="text/javascript">
var arr = new Array(6)
arr[0] = "黑龙江"
arr[1] = "吉林"
arr[2] = "辽宁"
arr[3] = "内蒙古"
arr[4] = "河北"
arr[5] = "山东"
document.write("原有数组元素:"+arr)
document.write("<br />")
document.write("获取的部分数组元素:"+arr.slice(2,4))
document.write("<br />")
document.write("获取部分元素后的数据:"+arr)
</script>
</body>
</html>
在IE 9.0中的浏览效果如图5-23所示,可以看出获取部分数组元素后的数组其前后是不变的。
图5-23 程序运行结果
5.4.8 对数组中的元素进行排序
使用sort()方法可以对数组的元素进行排序,语法格式如下:
arrayObject.sort(sortby)
其中,arrayObject为必选项,是数组对象;sortby为可选项,用来确定元素顺序的函数的名称,如果这个参数被省略,那么元素将按照ASCII字符顺序进行升序排序。
【例5.22】(实例文件:ch05\5.22.html)新建数组x并赋值1,20,8,12,6,7,使用sort方法排序数组,并输出x数组到页面。
<!DOCTYPE html>
<html>
<head>
<title>数组排序</title>
<script type="text/javascript">
var x=new Array(1,20,8,12,6,7); //创建数组
document.write("排序前数组:"+x.join(",")+"<p>"); //输出数组元素
x.sort(); //按字符升序排列数组
document.write("没有使用比较函数排序后数组:"+x.join(",")+"<p>"); //输出排序后数组
x.sort(asc); //有比较函数的升序排列
/*升序比较函数*/
function asc(a,b)
{
return a-b;
}
document.write("排序升序后数组:"+x.join(",")+"<p>");//输出排序后数组
x.sort(des); //有比较函数的降序排列
/*降序比较函数*/
function des(a,b)
{
return b-a;
}
document.write("排序降序后数组:"+x.join(","));//输出排序后数组
</script>
</head>
<body>
</body>
</html>
IE 9.0中浏览效果如图5-24所示。
图5-24 程序运行结果
在没有使用比较函数进行排序时,sort方法是按字符的ASCII值排序的,先从第一个字符比较,如果第一个字符相等,再比较第二个字符,以此类推。
对于数值型数据,如果按字符比较,得到的结果并不是用户所需要的,因此需要借助比较函数。比较函数有两个参数,分别代表每次排序时的两个数组项。sort()排序时每次比较两个数组项都会执行这个参数,并把两个比较的数组项作为参数传递给这个函数。当函数返回值大于0时就交换两个数组的顺序,否则就不交换,即函数返回值小于0,表示升序排列,函数返回值大于0,表示降序排列。
5.4.9 将数组转换成字符串
使用toString()方法可把数组转换为字符串,并返回结果。语法格式如下:
arrayObject.toString()
【例5.23】(实例文件:ch05\5.23.html)将数组转换成字符串。
<html>
<body>
<script type="text/javascript">
var arr = new Array(3)
arr[0] = "北京"
arr[1] = "上海"
arr[2] = "广州"
document.write(arr.toString())
</script>
</body>
</html>
IE 9.0中浏览效果如图5-25所示,可以看出数组中的元素之间用逗号分隔。
图5-25 程序运行结果
5.4.10 将数组转换成本地字符串
使用toLocaleString()方法可以把数组转换为本地的字符串,语法格式如下:
arrayObject.toLocaleString()
首先调用每个数组元素的toLocaleString()方法,然后使用地区特定的分隔符把生成的字符串连接起来,形成一个字符串。
【例5.24】(实例文件:ch05\5.24.html)将数组转换成本地的字符串。
<html>
<body>
<script type="text/javascript">
var arr = new Array(3)
arr[0] = "北京"
arr[1] = "上海"
arr[2] = "广州"
document.write(arr.toLocaleString())
</script>
</body>
</html>
IE 9.0中浏览效果如图5-26所示,可以看出数组中的元素之间用逗号分隔。
图5-26 程序运行结果
5.4.11 在数组开头插入数据
使用unshift()方法可以将指定的元素插入数组开始位置,并返回该数组,其语法格式如下:
arrayObject.unshift(newelement1,newelement2,....,newelementN)
其中,arrayObject是必选项,为Array的对象;newelementN是可选项,为要添加到该数组对象的新元素。
【例5.25】(实例文件:ch05\5.25.html)在数组开头插入数据。
<html>
<body>
<script type="text/javascript">
var arr = new Array()
arr[0] = "北京"
arr[1] = "上海"
arr[2] = "广州"
document.write(arr + "<br />")
document.write(arr.unshift("天津") + "<br />")
document.write(arr)
</script>
</body>
</html>
IE 9.0中浏览效果如图5-27所示。
图5-27 程序运行结果
5.5 创建和使用自定义对象
目前在JavaScript中,已经存在一些标准的类,例如Date、Array、RegExp、String、Math、Number等,这为编程提供了许多方便。但对于复杂的客户端程序而言,这些还远远不够。在JavaScript脚本语言中,还有浏览器对象、用户自定义对象和文本对象等对象,其中用户自定义对象占据举足轻重的地位。
JavaScript作为基于对象的编程语言,其对象实例通过构造函数来创建。每一个构造函数包括一个对象原型,定义了每个对象包含的属性和方法。在JavaScript脚本中创建自定义对象的方法主要有两种:通过定义对象的构造函数的方法和通过对象直接初始化的方法。
5.5.1 通过定义对象的构造函数的方法
在实际使用中,可首先定义对象的构造函数,然后使用new操作符来生成该对象的实例,从而创建自定义对象。
【例5.26】(实例文件:ch05\5.26.html)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>自定义对象</title>
<script language="JavaScript" type="text/javascript">
<!--
//对象的构造函数
function Student(iName,iAddress,iGrade,iScore)
{
this.name=iName;
this.address=iAddress;
this.grade=iGrade;
this.Score=iScore;
this.information=showInformation;
}
//定义对象的方法
function showInformation()
{
var msg="";
msg="学生信息:\n"
msg+="\n学生姓名 : "+this.name+" \n";
msg+="家庭地址 : "+this.address +"\n";
msg+="班级 : "+this.grade +" \n";
msg+="分数 : "+this.Score
window.alert(msg);
}
//生成对象的实例
var ZJDX=new Student("刘明明","新疆乌鲁木齐100号","401","99");
-->
</script>
</head>
<body>
<br>
<center>
<form>
<input type="button" value="查看" onclick="ZJDX.information()">
</form>
</center>
</body>
</html>
在IE 9.0中浏览效果如图5-28所示。单击“查看”按钮,即可看到含有学生信息的提示框,如图5-29所示。
图5-28 显示结果 图5-29 含有学生信息的提示框
在该方法中,用户需要先定义一个对象的构造函数,再通过new关键字来创建该对象的实例。定义对象的构造函数如下:
function Student(iName,iAddress,iGrade,iScore)
{
this.name=iName;
this.address=iAddress;
this.grade=iGrade;
this.score=iScore;
this.information=showInformation;
}
当调用该构造函数时,浏览器给新的对象分配内存,并将该对象传递给函数。this操作符是指向新对象引用的关键词,用于操作这个新对象。语句“this.name=iName;”使用作为函数参数传递过来的iName值在构造函数中给该对象的name属性赋值,该属性属于所有School对象,而不仅仅属于Student对象的某个实例,如例5.26中的ZJDX。对象实例的name属性被定义和赋值后,可以通过“var str=ZJDX.name;”方法访问此实例的该属性。
使用同样的方法继续添加address、grade、score等其他属性,但information不是对象的属性,而是对象的方法:
this.information=showInformation;
方法information指向的外部函数showInformation结构如下:
function showInformation()
{
var msg="";
msg="学生信息:\n"
msg+="\n学生姓名 : "+this.name+" \n";
msg+="家庭地址 : "+this.address +"\n";
msg+="班级 : "+this.grade +" \n";
msg+="分数 : "+this.Score
window.alert(msg);
}
同样,由于被定义为对象的方法,在外部函数中也可使用this操作符指向当前的对象,并通过this.name等访问它的某个属性。在构建对象的某个方法时,如果代码比较简单,也可以使用非外部函数的做法,改写Student对象的构造函数:
function Student(iName,iAddress,iGrade,iScore)
{
this.name=iName;
this.address=iAddress;
this.grade=iGrade;
this.score=iScore;
this.information=function()
{
var msg=" ";
msg="学生信息\n"
msg+="\n学生姓名 : "+this.name+" \n";
msg+="家庭地址 : "+this.address +"\n";
msg+="班级 : "+this.grade +" \n";
msg+="分数 : "+this.Score
window.alert(msg);
};
}
5.5.2 通过对象直接初始化的方法
此方法通过直接初始化对象来创建自定义对象,与定义对象的构造函数方法不同的是,该方法无须生成此对象的实例,将上面HTML文件中的JavaScript脚本部分做如下的修改:
<script language="JavaScript" type="text/javascript">
<!--
//直接初始化对象
var ZJDX={name:"刘明明",
address:" 新疆乌鲁木齐100号",
grade:" 401",
score:"99",
information:showInformation
};
//定义对象的方法
function showInformation()
{
var msg="";
msg="学生信息:\n"
msg+="\n学生姓名 : "+this.name+" \n";
msg+="家庭地址 : "+this.address +"\n";
msg+="班级 : "+this.grade +" \n";
msg+="分数 : "+this.Score
window.alert(msg);
}
-->
</script>
在IE浏览器中浏览修改后的HTML文档,可以看出与上面相同的结果。该方法适合只需生成某个应用对象并进行相关操作的情况下使用,代码紧凑,编程效率高,但若要生成若干个对象的实例,就必须为每个实例重复相同的代码结构,而只是参数不同而已,代码的重用性比较差,不符合面向对象的编程思路,所以应尽量避免使用该方法创建自定义对象。
5.5.3 修改和删除对象实例的属性
JavaScript脚本可动态地添加对象实例的属性,同时,也可动态修改、删除某个对象实例的属性,将上面HTML文件中的function showInformation()部分做如下的修改:
function showInformation()
{
var msg="";
msg="自定义对象实例:\n\n"
msg+=" 学生姓名 : "+this.name+" \n";
msg+=" 家庭地址 : "+this.address +"\n";
msg+=" 班级 : "+this.grade +" \n";
msg+=" 分数 : "+this.score+" \n\n";
//修改对象实例的score属性
this.score=88;
msg+="修改对象实例的属性:\n\n"
msg+=" 学生姓名 : "+this.name+" \n";
msg+=" 所在地址 : "+this.address +"\n";
msg+=" 班级 : "+this.grade +" \n";
msg+=" 分数 : "+this.score+" \n\n";
//删除对象实例的score属性
delete this.score;
msg+="删除对象实例的属性:\n\n"
msg+=" 学生姓名 : "+this.name+" \n";
msg+=" 家庭地址 : "+this.address +"\n";
msg+=" 班级 : "+this.grade +" \n";
msg+=" 分数 : "+this.score+" \n\n";
window.alert(msg);
}
保存更改,程序运行后,在原始页面单击“查看”按钮,弹出信息框如图5-30所示。
图5-30 修改和删除对象实例的属性
在执行“this.score=88;”语句后,对象实例的number属性值更改为88;而执行delete this.score语句后,对象实例的score属性变为Undefined,同任何不存在的对象属性一样为未定义类型,但并不能删除对象实例本身,否则将返回错误。
可见,JavaScript动态添加、修改、删除对象实例的属性过程十分简单,之所以称之为对象实例的属性而不是对象的属性,是因为该属性只在对象的特定实例中才存在,而不能通过某种方法将某个属性赋予特定对象的所有实例。
JavaScript脚本中的delete运算符用于删除对象实例的属性,而在C++中delete运算符不能删除对象的实例。
5.5.4 通过原型为对象添加新属性和新方法
JavaScript中对象的prototype属性,是用来返回对象类型原型引用的。使用prototype属性提供对象类的一组基本功能,并且对象的新实例会“继承”赋予该对象原型的操作。所有JavaScript内部对象都有只读的 prototype 属性。可以向其原型中动态添加功能(属性和方法),但该对象不能被赋予不同的原型。然而,用户定义的对象可以被赋予新的原型。
下面实例的作用是给已存在的对象添加新属性和新方法。
【例5.27】(实例文件:ch05\5.27.html)
<! DOCTYPE html>
<html>
<head>
<title>自定义对象</title>
<script language="JavaScript" type="text/javascript">
<!--
//对象的构造函数
function Student(iName,iAddress,iGrade,iScore)
{
this.name=iName;
this.address=iAddress;
this.grade=iGrade;
this.score=iScore;
this.information=showInformation;
}
//定义对象的方法
function showInformation()
{
var msg="";
msg="通过原型给对象添加新属性和新方法:\n\n"
msg+="原始属性:\n";
msg+="学生姓名: "+this.name+" \n";
msg+="家庭住址: "+this.address +"\n";
msg+="班级: "+this.grade +" \n";
msg+="分数: "+this.score+" \n\n";
msg+="新属性:\n";
msg+="性别: "+this.addAttributeOfSex+" \n";
msg+="新方法:\n";
msg+="方法返回 : "+this.addMethod+"\n";
window.alert(msg);
}
function MyMethod()
{
var AddMsg="New Method Of Object!";
return AddMsg;
}
//生成对象的实例
var ZJDX=new Student("刘明明","新疆乌鲁木齐100号","401","88");
Student.prototype.addAttributeOfSex="男";
Student.prototype.addMethod=MyMethod();
-->
</script>
</head>
<body>
<br>
<center>
<form>
<input type="button" value="查看" onclick="ZJDX.information()">
</form>
</center>
</body>
</html>
将上面的代码保存为HTML文件,再在IE浏览器中打开该网页。在打开的网页中单击“查看”按钮,即可看到含有新添加性别信息的提示框,如图5-31所示。
图5-31 通过原型给对象添加新属性和新方法
在上面的程序中,是通过调用对象的prototype属性给对象添加新属性和新方法的:
Student.prototype.addAttributeOfSex="男";
Student.prototype.addMethod=MyMethod();
原型属性为对象的所有实例所共享,用户利用原型添加对象的新属性和新方法后,可通过对象引用的方法来修改。
5.5.5 自定义对象的嵌套
与面向对象编程方法相同的是,JavaScript允许对象的嵌套使用,可以将对象的某个实例作为另外一个对象的属性来看待,如下面的程序:
<! DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>自定义对象嵌套</title>
<script language="JavaScript" type="text/javascript">
<!--
//对象的构造函数
//构造嵌套的对象
var StudentData={
age:"26",
Tel:"1810000000",
teacher:"张老师"
};
//构造被嵌入的对象
var ZJDX={
name:"刘明明",
address:"新疆乌鲁木齐100号",
grade:"401",
score:"86",
//嵌套对象StudentData
data:StudentData,
information:showInformation
};
//定义对象的方法
function showInformation()
{
var msg="";
msg="对象嵌套实例:\n\n";
msg+="被嵌套对象直接属性值:\n"
msg+="学生姓名: "+this.name+"\n";
msg+="家庭地址: "+this.address +"\n";
msg+="年级: "+this.grade +"\n";
msg+="分数: "+this.number +"\n\n";
msg+="访问嵌套对象直接属性值:\n"
msg+="年龄: "+this.data.age +"\n";
msg+="联系电话: "+this.data.Tel +" \n";
msg+="班主任: "+this.data.teacher +" \n";
window.alert(msg);
}
-->
</script>
</head>
<body>
<br>
<center>
<form>
<input type="button" value="查看" onclick="ZJDX.information()">
</form>
</center>
</body>
</html>
在上述JavaScript中先构造对象StudentData包含学生的相关联系信息,代码如下:
var StudentData={
age:"26",
Tel:"1810000000",
teacher:"张老师""
};
然后构建ZJDX对象,同时嵌入StudentData对象,代码如下所示:
var ZJDX={
name:"刘明明",
address:"新疆乌鲁木齐100号",
grade:"401",
score:"86",
//嵌套对象StudentData
data:StudentData,
information:showInformation
};
可以看出,在构建ZJDX对象时,StudentData对象作为其自身属性data的取值而引入,并可通过如下的代码进行访问:
this.data.age
this.data.Tel
this.data.teacher
程序运行后,在打开的网页中单击“查看”按钮,即可弹出信息框,如图5-32所示。
图5-32 自定义对象的嵌套
在创建对象时,浏览器自动为其分配内存空间,并在关闭当前页面时释放,下面将介绍对象创建过程中内存的分配和释放问题。
5.5.6 内存的分配和释放
JavaScript是基于对象的编程语言,而不是面向对象的编程语言,因此缺少指针的概念。面向对象的编程语言在动态分配和释放内存方面起着非常重要的作用,那么JavaScript中的内存如何管理呢?在创建对象的同时,浏览器自动为创建的对象分配内存空间,JavaScript将新对象的引用传递给调用的构造函数;而在对象清除时其占据的内存将被自动回收,其实整个过程都是浏览器的功劳,JavaScrip只是创建该对象。
浏览器中的这种内存管理机制称为“内存回收”,它动态分析程序中每个占据内存空间的数据(变量、对象等)。如果该数据对于程序标记为不可再用时,浏览器调用内部函数将其占据的内存空间释放,实现内存的动态管理。在自定义的对象使用过后,可以通过给其赋空值的方法来标记对象占据的空间是否可予以释放,如“ZJDX=null;”。浏览器将根据此标记动态释放其占据的内存,否则将保存该对象直至当前程序再次使用它为止。
5.6 实战演练——利用二维数组创建动态下拉菜单
二维数组又称为矩阵,行列数相等的矩阵称为方阵。对称矩阵:aij = aji,对角矩阵:n阶方阵的所有非零元素都集中在主对角线上。许多编程语言中都提供定义和使用二维或多维数组的功能。JavaScript通过Array对象创建的数组都是一维的,但是可以通过在数组元素中使用数组来实现二维数组。
下面的HTML文档就是通过使用一个二维数组来改变下拉菜单内容的:
<! DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE>动态改变下拉菜单内容</TITLE>
</HEAD>
<SCRIPT LANGUAGE=javascript>
//定义一个二维数组aCity,用于存放城市名称。
var aCity=new Array();
aCity[0]=new Array();
aCity[1]=new Array();
aCity[2]=new Array();
aCity[3]=new Array();
//赋值,每个省份的城市存放于数组的一行。
aCity[0][0]="--请选择--";
aCity[1][0]="--请选择--";
aCity[1][1]="广州市";
aCity[1][2]="深圳市";
aCity[1][3]="珠海市";
aCity[1][4]="汕头市";
aCity[1][5]="佛山市";
aCity[2][0]="--请选择--";
aCity[2][1]="长沙市";
aCity[2][2]="株州市";
aCity[2][3]="湘潭市";
aCity[3][0]="--请选择--";
aCity[3][1]="杭州市";
aCity[3][2]="宁波市";
aCity[3][3]="温州市";
function ChangeCity()
{
var i,iProvinceIndex;
iProvinceIndex=document.frm.optProvince.selectedIndex;
iCityCount=0;
while (aCity[iProvinceIndex][iCityCount]!=null)
iCityCount++;
//计算选定省份的城市个数
document.frm.optCity.length=iCityCount;//改变下拉菜单的选项数
for (i=0;i<=iCityCount-1;i++)//改变下拉菜单的内容
document.frm.optCity[i]=new Option(aCity[iProvinceIndex][i]);
document.frm.optCity.focus();
}
</SCRIPT>
<BODY ONfocus=ChangeCity()>
<H3>选择省份及城市</H3>
<FORM NAME="frm">
<P>省份:
<SELECT NAME="optProvince" SIZE="1" ONCHANGE=ChangeCity()>
<OPTION>--请选择--</OPTION>
<OPTION>广东省</OPTION>
<OPTION>湖南省</OPTION>
<OPTION>浙江省</OPTION>
</SELECT>
</P>
<P>城市:
<SELECT NAME="optCity" SIZE="1">
<OPTION>--请选择--</OPTION>
</SELECT>
</P>
</FORM>
</BODY>
</HTML>
在IE浏览器中打开上面的HTML文档,其显示结果如图5-33所示。在第一个下拉列表中选择一个省份,然后在第二个下拉列表即可看到相应的城市,如图5-34所示。
图5-33 显示结果 图5-34 选择省份对应的城市
5.7 疑难解惑
1. JavaScript支持的对象主要包括哪些?
JavaScript支持的对象主要包括几种。
JavaScript核心对象:包括同基本数据类型相关的对象(如String、Boolean、Number)、允许创建用户自定义和组合类型的对象(如Object、Array)和其他能简化JavaScript操作的对象(如Math、Date、RegExp、Function)。
浏览器对象:包括不属于JavaScript语言本身但被绝大多数浏览器所支持的对象,如控制浏览器窗口和用户交互界面的window对象、提供客户端浏览器配置信息的Navigator对象。
用户自定义对象:Web应用程序开发者用于完成特定任务而创建的自定义对象,可自由设计对象的属性、方法和事件处理程序,编程灵活性较大。
文本对象:由文本域构成的对象,在DOM中定义,同时赋予很多特定的处理方法,如insertData()、appendData()等。
2. 如何获取数组的长度?
获取数组长度的代码如下:
var arr=new Array();
var len=arr.length;
无论是传统编程语言,还是脚本语言,都具有数据类型、常量和变量、运算符、表达式、注释语句、流程控制语句等基本元素构成,这些基本元素构成了编程基础。本章将主要讲述JavaScript编程的基本知识。
回试读目录
文档对象模型(DOM)是一个基础性的概念,主要涉及网页页面元素的层次关系。理解文档对象模型的概念,对于编写出高效、实用的JavaScript程序是非常有帮助的。而事件和事件处理是网页设计中必须面对的问题,也是使网页变得多姿多彩的重要手段。 本章从JavaScript中的文档对象模型的基本概念入手,介绍了文档对象的层次、产生过程以及常用的属性和方法。接着介绍了JavaScript中对象的事件,使用JavaScript编程时,可以通过捕获不同的事件进行相应的事件处理。如果要熟练使用JavaScript,除了熟