《征服Ajax:Web2.0开发技术详解》试读版作者:王沛冯曼菲出版社:人民邮电出版社全国各大书店均有销售网上购书地址:://=29998PDF文件使用pdfFactory试用版本创建开发模式中,JavaScript是一种点缀的作用,完成很有限的功能,诸如表单验证之类。其语言本身也一直被当作过程化的语言使用,很难完成复杂的功能。而Ajax的出现使得复杂脚本成为必需的组成部分,这就对JavaScript程序设计提出了新的要求,很多Ajax应用开始利用JavaScript面向对象的性质进行开发,使逻辑更加清晰。事实上,JavaScript提供了完善的机制来实现面向对象的开发思想。本章假设读者已经了解面向对象思想的基本概念,熟悉对象、类、继承等基本术语。以此为基础,将重点介绍如何在JavaScript中使用面向对象的思想,包括实现的原理、机制和技巧。6.1JavaScript中支持面向对象的基础6.1.1用定义函数的方式定义类在面向对象的思想中,最核心的概念之一就是类。一个类表示了具有相似性质的一类事物的抽象,通过实例化一个类,可以获得属于该类的一个实例(即对象)。在JavaScript中定义一个类的方法如下:functionclass1(){//类成员的定义及构造函数}这里class1既是一个函数也是一个类。作为函数,它可以理解为类的构造函数,负责初始化的工作。6.1.2使用new操作符获得一个类的实例在前面介绍基本对象时,已经用过new操作符,例如:newDate();表示创建一个日期对象,而Date就是表示日期的类,只是这个类是由JavaScript内部提供的,而不是由用户定义的。new操作符不仅对内部类有效,对用户定义的类也是同样的用法,对于上节定义的class1,也可以用new来获取一个实例:functionclass1(){//类成员的定义及构造函数}varobj1=newclass1();抛开类的概念,从代码的形式上来看,class1就是一个函数,那么是不是所有的函数都可以用new来操作呢?答案是肯定的。在JavaScript中,函数和类就是一个概念,当new一个函数时,就会返回一个对象。如果这个函数中没有初始化类成员,那就会返回一个空的对象。例如://定义一个hello函数functionhello(){PDF文件使用pdfFactory试用版本创建à(“hello”);}//通过new一个函数获得一个对象varobj=newhello();alert(typeof(obj));从运行结果看,执行了hello函数,同时obj也获得了一个对象的引用。事实上,当new一个函数时,这个函数就是所代表类的构造函数,其中的所有代码都可以看作为了初始化一个对象而工作。用于表示类的函数也称之为构造器。6.1.3使用方括号([])引用对象的属性和方法在JavaScript中,每个对象可以看作是多个属性(方法)的集合,引用一个属性(方法)很简单,即:对象名.属性(方法)名除此之外,还可以用方括号的形式来引用:对象名[“属性(方法)名”]注意,这里的方法名和属性名是一个字符串,而非原先点号后面的标识符,例如:vararr=newArray();//为数组添加一个元素arr[“push”](“abc”);//获得数组的长度varlen=arr[“length”];//输出数组的长度alert(len);图4.1显示了执行的结果。图4.1引用对象属性示例由此可见,上面的代码等价于:vararr=newArray();//为数组添加一个元素arr.push(“abc”);//获得数组的长度varlen=arr.length;//输出数组的长度alert(len);这种引用属性(方法)的方式和数组类似,也体现出一个JavaScript对象就是一组属性(方法)的集合这个性质。这种用法适合不确定具体要引用哪个属性(方法)的场合,例如:一个对象用于表示用户资料,这时一个字符串表示要使用哪个属性,那就可以用这种方式来引用:scriptlanguage=JavaScripttype=text/javascript!--//定义了一个User类,包括两个成员age和sex,并指定了初始值。PDF文件使用pdfFactory试用版本创建à(){this.age=21;this.sex=male;}//创建user对象varuser=newUser();//根据下拉列表框显示用户的信息functionshow(slt){if(slt.selectedIndex!=0){alert(user[slt.value]);}}//--/script!--下拉列表框用于选择用户信息--selectonchange=show(this)option请选择需要查看的信息:/optionoptionvalue=age年龄/optionoptionvalue=sex性别/option/select在这段代码中,使用一个下拉列表框让用户选择查看哪个信息,每个选项的value就表示用户对象的属性名称。这时如果不采用方括号的形式,就必须使用如下代码来达到预期效果:functionshow(slt){if(slt.selectedIndex!=0){if(slt.value==”age”)alert(user.age);if(slt.value==”sex”)alert(user.sex);}}而使用方括号语法,则只需写为:alert(user[slt.value]);由此可见,方括号语法更像一种参数语法,可用一个变量来表示引用对象的哪个属性。如果不采用这种方法,又不想用条件判断,可以使用eval函数:alert(eval(“user.”+slt.value));这里利用eval函数的性质,执行了一段动态生成的代码,并返回了结果。实际上,在前面讲述document的集合对象时,就有类似方括号的用法,比如引用页面中一个名为“theForm”的表单对象,曾经的用法是:document.forms[“theForm”];其实也可以写为:document.forms.theForm;但这里的forms对象是一个内部对象,和自定义对象不同的是,它还可以用索引来引用其中的一个属性。6.1.4动态添加、修改、删除对象的属性和方法上一节介绍了如何引用一个对象的属性和方法,现在介绍如何为一个对象添加、修改或者删除属性和方法。在其他语言中,对象一旦生成,就不可更改了,要为一个对象添加修改成员必须要在对应的类中修改,并重新实例化,而且程序必须经过重新编译。JavaScript中却非如此,它提PDF文件使用pdfFactory试用版本创建à供了灵活的机制来修改对象的行为,可以动态添加、修改、删除属性和方法。例如首先使用类Object来创建一个空对象user:varuser=newObject();1.添加属性这时user对象没有任何属性和方法,显然没有任何用途。但可以为它动态的添加属性和方法,例如:user.name=”jack”;user.age=21;user.sex=”male”;通过上述语句,user对象便具有了三个属性:name、age和sex。下面输出这三个语句:alert(user.name);alert(user.age);alert(user.sex);由代码运行效果可知,三个属性已经完全属于user对象了。2.添加方法添加方法的过程和属性类似:user.alert=function(){alert(“mynameis:”+this.name);}这就为user对象添加了一个方法“alert”,通过执行它,可以弹出一个对话框显示自己的名字介绍:user.alert();图4.2显示了执行的结果。图4.2为user对象添加alert方法示例3.修改属性修改一个属性的过程就是用新的属性替换旧的属性,例如:user.name=”tom”;user.alert=function(){alert(“hello,”+this.name);}这样就修改了user对象name属性的值和alert方法,它从显示“mynameis”变为了显示“hello”。4.删除属性删除一个属性的过程也很简单,就是将其置为undefined:user.name=undefined;user.alert=undefined;这样就删除了name属性和alert方法。在之后的代码中,这些属性变的不可用。在添加、修改或者删除属性时,和引用属性相同,也可以采用方括号([])语法:user[“name”]=”tom”;PDF文件使用pdfFactory试用版本创建à使用这种方式还有一个额外的特点,就是可以使用非标识符字符串作为属性名称,例如标识符中不允许以数字开头或者出现空格,但在方括号([])语法中却可以使用:user[“myname”]=”tom”;需要注意,在使用这种非标识符作为名称的属性时,仍然要用方括号语法来引用:alert(user[“myname”]);而不能写为:alert(user.myname);利用对象的这种性质,甚至可以很容易实现一个简单的哈希表,在本书的后面将会看到其应用。此可见,JavaScript中的每个对象都是动态可变的,这给编程带来了很大的灵活性,也和其他语言产生了很大的区别,读者可以体会这种性质。6.1.5使用大括号({})语法创建无类型对象传统的面向对象语言中,每个对象都会对应到一个类。而上一节讲this指针时提到,JavaScript中的对象其实就是属性(方法)的一个集合,并没有严格意义的类的概念。所以它提供了另外一种简单的方式来创建对象,即大括号({})语法:{property1:statement,property2:statement2,…,propertyN:statmentN}通过大括号括住多个属性或方法及其定义(这些属性或方法用逗号隔开),来实现对象的定义,这段代码就直接定义个了具有n个属性或方法的对象,其中属性名和其定义之间用冒号(:)隔开。例如:scriptlanguage=JavaScripttype=text/javascript!--varobj={};//定义了一个空对象varuser={name:jack,//定义了name属性,初始化为jackfavoriteColor:[red,green,black,white],//定义了颜色喜好数组hello:function(){//定义了方法helloalert(hello,+this.name);},sex:male//定义了性别属性sex,初始化为sex}//调用user对象的方法hellouser.hello();//--/script第一行定义了一个无类型对象obj,它等价于:varobj=newObject();接着定义了一个对象user及其属性和方法。注意,除了最后一个属性(方法)定义,其他的必须以逗号(,)结尾。其实,使用动态增减属性的方法也可以定义一个完全相同的user对象,读者不妨使用前面介绍的方法做一个尝试。使用这种方式来定义对象,还可以使用字符串作为属性(方法)名,例如:varobj={“001”:”abc”}PDF文件使用pdfFactory试用版本创建à定义了一个属性“001”,这并不是一个有效的标识符,所以要引用这个属性必须使用方括号语法:o