关闭

关闭

封号提示

内容

首页 征服Ajax - Web20开发技术详解试读版.pdf

征服Ajax - Web20开发技术详解试读版.pdf

征服Ajax - Web20开发技术详解试读版.pdf

上传者: al_10000 2014-02-20 评分 3 0 31 4 140 暂无简介 简介 举报

简介:本文档为《征服Ajax - Web20开发技术详解试读版pdf》,可适用于IT/计算机领域,主题内容包含《征服Ajax:Web开发技术详解》试读版作者:王沛冯曼菲出版社:人民邮电出版社全国各大书店均有销售网上购书地址:http:wwwdearbookc符等。

《征服Ajax:Web开发技术详解》试读版作者:王沛冯曼菲出版社:人民邮电出版社全国各大书店均有销售网上购书地址:http:wwwdearbookcomcnbookhttp:wwwchinapubcomcomputerscommoninfoaspid=PDF文件使用"pdfFactory"试用版本创建wwwfineprintcn第章JavaScript面向对象程序设计在传统的Web开发模式中JavaScript是一种点缀的作用完成很有限的功能诸如表单验证之类。其语言本身也一直被当作过程化的语言使用很难完成复杂的功能。而Ajax的出现使得复杂脚本成为必需的组成部分这就对JavaScript程序设计提出了新的要求很多Ajax应用开始利用JavaScript面向对象的性质进行开发使逻辑更加清晰。事实上JavaScript提供了完善的机制来实现面向对象的开发思想。本章假设读者已经了解面向对象思想的基本概念熟悉对象、类、继承等基本术语。以此为基础将重点介绍如何在JavaScript中使用面向对象的思想包括实现的原理、机制和技巧。JavaScript中支持面向对象的基础用定义函数的方式定义类在面向对象的思想中最核心的概念之一就是类。一个类表示了具有相似性质的一类事物的抽象通过实例化一个类可以获得属于该类的一个实例(即对象)。在JavaScript中定义一个类的方法如下:functionclass(){类成员的定义及构造函数}这里class既是一个函数也是一个类。作为函数它可以理解为类的构造函数负责初始化的工作。使用new操作符获得一个类的实例在前面介绍基本对象时已经用过new操作符例如:newDate()表示创建一个日期对象而Date就是表示日期的类只是这个类是由JavaScript内部提供的而不是由用户定义的。new操作符不仅对内部类有效对用户定义的类也是同样的用法对于上节定义的class也可以用new来获取一个实例:functionclass(){类成员的定义及构造函数}varobj=newclass()抛开类的概念从代码的形式上来看class就是一个函数那么是不是所有的函数都可以用new来操作呢?答案是肯定的。在JavaScript中函数和类就是一个概念当new一个函数时就会返回一个对象。如果这个函数中没有初始化类成员那就会返回一个空的对象。例如:定义一个hello函数functionhello(){PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcnalert(“hello”)}通过new一个函数获得一个对象varobj=newhello()alert(typeof(obj))从运行结果看执行了hello函数同时obj也获得了一个对象的引用。事实上当new一个函数时这个函数就是所代表类的构造函数其中的所有代码都可以看作为了初始化一个对象而工作。用于表示类的函数也称之为构造器。使用方括号()引用对象的属性和方法在JavaScript中每个对象可以看作是多个属性(方法)的集合引用一个属性(方法)很简单即:对象名属性(方法)名除此之外还可以用方括号的形式来引用:对象名“属性(方法)名”注意这里的方法名和属性名是一个字符串而非原先点号后面的标识符例如:vararr=newArray()为数组添加一个元素arr“push”(“abc”)获得数组的长度varlen=arr“length”输出数组的长度alert(len)图显示了执行的结果。图引用对象属性示例由此可见上面的代码等价于:vararr=newArray()为数组添加一个元素arrpush(“abc”)获得数组的长度varlen=arrlength输出数组的长度alert(len)这种引用属性(方法)的方式和数组类似也体现出一个JavaScript对象就是一组属性(方法)的集合这个性质。这种用法适合不确定具体要引用哪个属性(方法)的场合例如:一个对象用于表示用户资料这时一个字符串表示要使用哪个属性那就可以用这种方式来引用:<scriptlanguage="JavaScript"type="textjavascript"><!定义了一个User类包括两个成员age和sex并指定了初始值。PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcnfunctionUser(){thisage=thissex="male"}创建user对象varuser=newUser()根据下拉列表框显示用户的信息functionshow(slt){if(sltselectedIndex!=){alert(usersltvalue)}}><script><!下拉列表框用于选择用户信息><selectonchange="show(this)"><option>请选择需要查看的信息:<option><optionvalue="age">年龄<option><optionvalue="sex">性别<option><select>在这段代码中使用一个下拉列表框让用户选择查看哪个信息每个选项的value就表示用户对象的属性名称。这时如果不采用方括号的形式就必须使用如下代码来达到预期效果:functionshow(slt){if(sltselectedIndex!=){if(sltvalue==”age”)alert(userage)if(sltvalue==”sex”)alert(usersex)}}而使用方括号语法则只需写为:alert(usersltvalue)由此可见方括号语法更像一种参数语法可用一个变量来表示引用对象的哪个属性。如果不采用这种方法又不想用条件判断可以使用eval函数:alert(eval(“user”sltvalue))这里利用eval函数的性质执行了一段动态生成的代码并返回了结果。实际上在前面讲述document的集合对象时就有类似方括号的用法比如引用页面中一个名为“theForm”的表单对象曾经的用法是:documentforms“theForm”其实也可以写为:documentformstheForm但这里的forms对象是一个内部对象和自定义对象不同的是它还可以用索引来引用其中的一个属性。动态添加、修改、删除对象的属性和方法上一节介绍了如何引用一个对象的属性和方法现在介绍如何为一个对象添加、修改或者删除属性和方法。在其他语言中对象一旦生成就不可更改了要为一个对象添加修改成员必须要在对应的类中修改并重新实例化而且程序必须经过重新编译。JavaScript中却非如此它提PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcn供了灵活的机制来修改对象的行为可以动态添加、修改、删除属性和方法。例如首先使用类Object来创建一个空对象user:varuser=newObject().添加属性这时user对象没有任何属性和方法显然没有任何用途。但可以为它动态的添加属性和方法例如:username=”jack”userage=usersex=”male”通过上述语句user对象便具有了三个属性:name、age和sex。下面输出这三个语句:alert(username)alert(userage)alert(usersex)由代码运行效果可知三个属性已经完全属于user对象了。.添加方法添加方法的过程和属性类似:useralert=function(){alert(“mynameis:”thisname)}这就为user对象添加了一个方法“alert”通过执行它可以弹出一个对话框显示自己的名字介绍:useralert()图显示了执行的结果。图为user对象添加alert方法示例.修改属性修改一个属性的过程就是用新的属性替换旧的属性例如:username=”tom”useralert=function(){alert(“hello,”thisname)}这样就修改了user对象name属性的值和alert方法它从显示“mynameis”变为了显示“hello”。.删除属性删除一个属性的过程也很简单就是将其置为undefined:username=undefineduseralert=undefined这样就删除了name属性和alert方法。在之后的代码中这些属性变的不可用。在添加、修改或者删除属性时和引用属性相同也可以采用方括号()语法:user“name”=”tom”PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcn使用这种方式还有一个额外的特点就是可以使用非标识符字符串作为属性名称例如标识符中不允许以数字开头或者出现空格但在方括号()语法中却可以使用:user“myname”=”tom”需要注意在使用这种非标识符作为名称的属性时仍然要用方括号语法来引用:alert(user“myname”)而不能写为:alert(usermyname)利用对象的这种性质甚至可以很容易实现一个简单的哈希表在本书的后面将会看到其应用。此可见JavaScript中的每个对象都是动态可变的这给编程带来了很大的灵活性也和其他语言产生了很大的区别读者可以体会这种性质。使用大括号({})语法创建无类型对象传统的面向对象语言中每个对象都会对应到一个类。而上一节讲this指针时提到JavaScript中的对象其实就是属性(方法)的一个集合并没有严格意义的类的概念。所以它提供了另外一种简单的方式来创建对象即大括号({})语法:{property:statement,property:statement,…,propertyN:statmentN}通过大括号括住多个属性或方法及其定义(这些属性或方法用逗号隔开)来实现对象的定义这段代码就直接定义个了具有n个属性或方法的对象其中属性名和其定义之间用冒号(:)隔开。例如:<scriptlanguage="JavaScript"type="textjavascript"><!varobj={}定义了一个空对象varuser={name:"jack",定义了name属性初始化为jackfavoriteColor:"red","green","black","white",定义了颜色喜好数组hello:function(){定义了方法helloalert("hello,"thisname)},sex:"male"定义了性别属性sex初始化为sex}调用user对象的方法hellouserhello()><script>第一行定义了一个无类型对象obj它等价于:varobj=newObject()接着定义了一个对象user及其属性和方法。注意除了最后一个属性(方法)定义其他的必须以逗号(,)结尾。其实使用动态增减属性的方法也可以定义一个完全相同的user对象读者不妨使用前面介绍的方法做一个尝试。使用这种方式来定义对象还可以使用字符串作为属性(方法)名例如:varobj={“”:”abc”}PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcn这就给对象obj定义了一个属性“”这并不是一个有效的标识符所以要引用这个属性必须使用方括号语法:obj“”由此可见无类型对象提供了一种创建对象的简便方式它以紧凑和清晰的语法将一个对象体现为一个完整的实体。而且也有利于减少代码的体积这对JavaScript代码来说尤其重要因为要通过网络来下载减少体积意味着提高了访问速度。prototype原型对象prototype对象是实现面向对象的一个重要机制。每个函数(function)其实也是一个对象它们对应的类是“Function”但它们身份特殊每个函数对象都具有一个子对象prototype。顾名思义prototype表示了该函数的原型而函数也即是类prototype实际上就是表示了一个类的成员的集合。当通过new来获取一个类的对象时prototype对象的成员都会成为实例化对象的成员。既然prototype是一个对象可以使用前面两节介绍的方法对其进行动态的修改这里先给出一个简单的例子:定义了一个空类functionclass(){empty}对类的prototype对象进行修改增加方法methodclassprototypemethod=function(){alert(“it’satestmethod”)}创建类class的实例varobj=newclass()调用obj的方法methodobjmethod()图显示了执行的结果。图使用prototype示例深入认识JavaScript中的函数概述函数是进行模块化程序设计的基础然而到现在为止对JavaScript中函数的介绍还停留在一个很基础的阶段。尽管这已经足以应付一般的应用开发但是对于复杂的Ajax应用必须对函数有更深入的了解。JavaScript中的函数不同于其它的语言每个函数都是作为一PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcn个对象被维护和运行的。通过函数对象的性质可以很方便的将一个函数赋值给一个变量或者将函数作为参数传递。在继续讲述之前先看一下函数的使用语法:functionfunc(…){…}varfunc=function(…){…}varfunc=functionfunc(…){…}varfunc=newFunction()或许现在这些代码看上去有点匪夷所思但这些都是声明函数的正确语法。它们和其它语言中常见的函数或者之前介绍的函数定义方式有着很大的区别。那么在JavaScript中为什么能这么写?它所遵循的语法是什么呢?这些正是下面要介绍的内容。认识函数对象(FunctionObject)可以用function关键字定义一个函数对于每个函数可以为其指定一个函数名通过函数名来进行调用。这些都是代码给用户的印象而在JavaScript解释执行的时候实际上每个函数都是被维护为一个对象这就是本小节将要介绍的函数对象(FunctionObject)。函数对象与其它用户所定义的对象有着本质的区别这一类对象被称之为内部对象例如日期对象(Date)、数组对象(Array)、字符串对象(String)都是属于内部对象。换句话说这些内置对象的构造器是由JavaScript本身所定义的:通过执行newArray()这样的语句返回一个对象JavaScript内部有一套机制来初始化返回的对象而不是由用户来指定对象的构造方式。在JavaScript中函数对象对应的类型是Function正如数组对象对应的类型是Array日期对象对应的类型是Date一样可以通过newFunction()来创建一个函数对象也可以通过function关键字来创建一个对象。为了便于理解将函数对象的创建和数组对象的创建来比较。先看数组对象:下面两行代码的作用是一样的都是创建一个数组对象myArray:varmyArray=等价于varmyArray=newArray()同样下面的两段代码也是等价的都是创建一个函数myFunction:functionmyFunction(a,b){returnab}等价于varmyFunction=newFunction("a","b","returnab")现在上面的代码还有些难以理解但是通过和构造数组对象语句的比较可以清楚的看到函数的对象本质前面介绍的函数声明是上述代码的第一种方式而在解释器内部当遇到这种语法时就会自动构造一个Function对象将函数作为一个内部的对象来存储和运行。从这里也可以看到一个函数对象名称(函数变量)和一个普通变量名称具有同样的规范都可以通过变量名来引用这个变量但是函数变量名后面可以跟上括号和参数列表来进行函数调用。也许不会有人通过newFunction()的形式来创建一个函数因为一个函数体通常会有多条语句如果将它们以一个字符串的形式作为参数传递那么代码的可读性会非常的差。下面介绍一下其使用语法:varfuncName=newFunction(p,p,,pn,body)参数的类型都是字符串p到pn表示所创建函数的参数名称列表body表示所创建函数的函数体语句而funcName就是所创建函数的名称了。可以不指定任何参数创建一个空函数不指定funcName创建一个无名函数当然那样的函数什么用处都没有。PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcn需要注意的是前面说p到pn是参数名称的列表这意味着p不仅仅只能代表一个参数它也可以是一个逗号格开的参数列表例如下面的定义是等价的:newFunction("a","b","c","returnabc")newFunction("a,b,c","returnabc")newFunction("a,b","c","returnabc")JavaScript引入Function类型并提供newFunction()这样的语法来创建函数并不是毫无意义的在后面可以看到函数作为一个对象它本身就可以具有一些方法和属性而为函数对象添加属性和方法就必须借助于Function这个类型。现在已经认识到了函数的本质它其实是一个内部对象由JavaScript解释器决定其运行方式。通过上述代码创建的函数在程序中可以使用函数名进行调用。于是在本节开头列出的函数定义问题也得到了解释:它们都是创建函数对象的正确语法。注意直接在函数声明后面加上括号就表示创建完成后立即进行函数调用例如:vari=function(a,b){returnab}(,)alert(i)这段代码会显示变量i的值等于。i是表示返回的值而不是创建的函数因为括号“(”比等号“=”有更高的优先级。这样的代码可能并不常用但当用户想在很长的代码段中进行模块化设计或者想避免命名冲突这是一个不错的解决办法。需要注意的是尽管下面两种创建函数的方法是等价的:functionfuncName(){函数体}等价于varfuncName=function(){函数体}但前面一种方式创建的是有名函数而后面是创建了一个无名函数只是让一个变量指向了这个无名函数。在使用上仅有一点区别就是:对于有名函数它可以出现在调用之后再定义而对于无名函数它必须是在调用之前就已经定义。例如:<scriptlanguage="JavaScript"type="textjavascript"><!func()varfunc=function(){alert()}><script>这段语句将产生func未定义的错误而:<scriptlanguage="JavaScript"type="textjavascript"><!func()functionfunc(){alert()}><script>则能够正确执行甚至下面的语句也能正确执行:<scriptlanguage="JavaScript"type="textjavascript"><!PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcnfunc()varsomeFunc=functionfunc(){alert()}><script>由此可见尽管JavaScript是一门解释型的语言但它会在进行函数调用时检查整个代码中是否存在相应的函数定义这个函数名只有是通过functionfuncName()形式定义的才会有效而不能是匿名函数。函数对象和其他内部对象的关系除了函数对象还有很多内部对象比如:Object、Array、Date、RegExp、Math、Error。更准确的说这些名称实际上表示一个类型可以通过new操作符返回一个对象。然而函数对象和其它对象不同当用typeof得到一个函数对象的类型时它仍然会返回字符串“function”而typeof一个数组对象或其它的对象时它会返回字符串“object”。下面的代码示例了typeof不同类型的情况:alert(typeof(Function)))alert(typeof(newFunction()))alert(typeof(Array))alert(typeof(Object))alert(typeof(newArray()))alert(typeof(newDate()))alert(typeof(newObject()))运行这段代码可以发现:前面条语句都会显示“function”而后面条语句则显示“object”可见new一个function实际上是返回一个函数。这与其它的对象有很大的不同。其它的类型Array、Object等都会通过new操作符返回一个普通对象。尽管函数本身也是一个对象但它与普通的对象还是有区别的因为它同时也是对象构造器也就是说可以new一个函数来返回一个对象这在前面已经有过描述。所有typeof返回“function”的对象都是函数对象。也称这样的对象为构造器(constructor)因而所有的构造器都是对象但不是所有的对象都是构造器。既然函数本身也是一个对象它们的类型是function联想到C、Java等面向对象语言的类定义可以猜测到Function类型的作用所在那就是可以给函数对象本身定义一些方法和属性借助于函数的prototype对象可以很方便的修改和扩充Function类型的定义例如下面先扩展了函数类型Function为其增加了method方法作用是弹出对话框显示"function":Functionprototypemethod=function(){alert("function")}functionfunc(a,b,c){returnabc}funcmethod()funcmethodmethod()注意最后一个语句:funcmethodmehotd()它调用了method这个函数对象的method方法。虽然看上去有点容易混淆但仔细观察一下语法还是很明确的:这是一个递归的定义。因为method本身也是一个函数所以它同样具有函数对象的属性和方法所有PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcn对Function类型的方法扩充都具有这样的递归性质。Function是所有函数对象的基础而Object则是所有对象(包括函数对象)的基础。在JavaScript中任何一个对象都是Object的实例因此可以修改Object这个类型来让所有的对象具有一些通用的属性和方法修改Object类型是通过prototype来完成的:ObjectprototypegetType=function(){returntypeof(this)}vararray=newArray()functionfunc(a,b){returnab}alert(arraygetType())alert(funcgetType())上面的代码为所有的对象添加了getType方法作用是返回该对象的类型。两条alert语句分别会显示“object”和“function”。将函数作为参数传递在前面已经介绍了函数的对象本质每个函数在都被表示为一个特殊的对象可以方便的将其赋值给一个变量再通过这个变量名进行函数调用。作为一个变量它可以以参数的形式传递给另一个函数这在前面介绍JavaScript事件处理机制中已经看到过这样的用法或许前面还对语法难以理解但到了现在一切都变得顺其自然例如下面的程序将func作为参数传递给func:functionfunc(theFunc){theFunc()}functionfunc(){alert("ok")}func(func)在最后一条语句中func作为一个对象传递给了func的形参theFunc再由func内部进行theFunc的调用。事实上将函数作为参数传递或者是将函数赋值给其它变量是所有事件机制的基础。例如如果需要在页面载入时进行一些初始化工作可以先定义一个init的初始化函数再通过windowonload=init语句将其绑定到页面载入完成的事件。这里的init就是一个函数对象它可以加入window的onload事件列表也正源于它的对象本质这和C语言、C语言的函数指针概念有很大的相似性。传递给函数的隐含参数:arguments当进行函数调用时除了指定的参数外还创建一个隐含的对象arguments。arguments是一个类似数组但不是数组的对象说它类似是因为它具有数组一样的访问性质可以用argumentsindex这样的语法取值拥有数组长度属性length。arguments对象存储的是实际传递给函数的参数而不只局限于函数声明所定义的参数列表例如:functionfunc(a,b){alert(a)PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcnalert(b)for(vari=i<argumentslengthi){alert(argumentsi)}}func(,,)代码运行时会依次显示:。因此在定义函数的时候即使不指定参数列表仍然可以通过arguments引用到所获得的参数这给编程带来了很大的灵活性。arguments对象的另一个属性是callee它表示对函数对象本身的引用这有利于实现无名函数的递归或者保证函数的封装性例如使用递归来计算到n的自然数之和:varsum=function(n){if(==n)returnelsereturnnsum(n)}alert(sum())其中函数内部包含了对sum自身的调用然而对于JavaScript来说函数名仅仅是一个变量名在函数内部调用sum即相当于调用一个全局变量不能很好的体现出是调用自身所以使用argumentscallee属性会是一个较好的办法:varsum=function(n){if(==n)returnelsereturnnargumentscallee(n)}alert(sum())callee属性并不是arguments不同于数组对象的唯一特征下面的代码说明了arguments不是由Array类型创建:Arrayprototypep=alert(newArray()p)functionfunc(){alert(argumentsp)}func()运行代码可以发现第一个alert语句显示为即表示数组对象拥有属性p而func调用则显示为“undefined”即p不是arguments的属性由此可见arguments并不是一个数组对象。函数的apply、call方法和length属性JavaScript为函数对象定义了两个方法:apply和call它们的作用都是将函数绑定到另外一个对象上去运行两者仅在定义参数的方式有所区别:Functionprototypeapply(thisArg,argArray)Functionprototypecall(thisArg,arg,arg…)从函数原型可以看到第一个参数都被取名为thisArg也就是说所有函数内部的this指针都会被赋值为thisArg这就达到了将函数作为另外一个对象的方法运行的目的。两个方法除了thisArg参数都是为Function对象传递的参数。下面的代码说明了apply和call方法的工作方式:定义一个函数func具有属性p和方法Afunctionfunc(){thisp="func"PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcnthisA=function(arg){alert(thisparg)}}定义一个函数func具有属性p和方法Bfunctionfunc(){thisp="func"thisB=function(arg){alert(thisparg)}}varobj=newfunc()varobj=newfunc()objA("byA")显示funcbyAobjB("byB")显示funcbyBobjAapply(obj,"byA")显示funcbyA其中“byA”是仅有一个元素的数组下同objBapply(obj,"byB")显示funcbyBobjAcall(obj,"byA")显示funcbyAobjBcall(obj,"byB")显示funcbyB可以看出obj的方法A被绑定到obj运行后整个函数A的运行环境就转移到了obj即this指针指向了obj。同样obj的函数B也可以绑定到obj对象去运行。代码的最后行显示了apply和call函数参数形式的区别。与arguments的length属性不同函数对象的还有一个参数相关的属性length它表示函数定义时所指定参数的个数而非调用时实际传递的参数个数。例如下面的代码将显示:functionsum(a,b){returnab}alert(sumlength)深入认识JavaScript中的this指针this指针是面向对象程序设计中的一项重要概念它表示当前运行的对象。在实现对象的方法时可以使用this指针来获得该对象自身的引用。和传统意义的面向对象的语言不同JavaScript中的this指针是一个动态的变量一个方法内的this指针并不是始终指向定义该方法的对象的在上一节讲函数的apply和call方法时已经有过这样的例子。为了方便大家理解再来看下面的例子:<scriptlanguage="JavaScript"type="textjavascript"><!创建两个空对象varobj=newObject()varobj=newObject()给两个对象都添加属性p并分别等于和objp=objp=给obj添加方法用于显示p的值objgetP=function(){alert(thisp)表面上this指针指向的是obj}调用obj的getP方法objgetP()PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcn使obj的getP方法等于obj的getP方法objgetP=objgetP调用obj的getP方法objgetP()><script>从代码的执行结果看分别弹出对话框和。由此可见getP函数仅定义了一次在不同的场合运行显示了不同的运行结果这是有this指针的变化所决定的。在obj的getP方法中this就指向了obj对象而在obj的getP方法中this就指向了obj对象并通过this指针引用到了两个对象都具有的属性p。由此可见JavaScript中的this指针是一个动态变化的变量它表明了当前运行该函数的对象。由this指针的性质也可以更好的理解JavaScript中对象的本质:一个对象就是由一个或多个属性(方法)组成的集合。每个集合元素不是仅能属于一个集合而是可以动态的属于多个集合。这样一个方法(集合元素)由谁调用this指针就指向谁。实际上前面介绍的apply方法和call方法都是通过强制改变this指针的值来实现的使this指针指向参数所指定的对象从而达到将一个对象的方法作为另一个对象的方法运行的效果。同时每个对象集合的元素(即属性或方法)也是一个独立的部分全局函数和作为一个对象方法定义的函数之间没有任何区别因为可以把全局函数和变量看作为window对象的方法和属性。也可以使用new操作符来操作一个对象的方法来返回一个对象这样一个对象的方法也就可以定义为类的形式其中的this指针则会指向新创建的对象。在后面可以看到这时对象名可以起到一个命名空间的作用这是使用JavaScript进行面向对象程序设计的一个技巧。例如:varnamespace=newObject()namespaceclass=function(){初始化对象的代码}varobj=newnamespaceclass()这里就可以把namespace看成一个命名空间。由于对象属性(方法)的动态变化特性一个对象的两个属性(方法)之间的互相引用必须要通过this指针而在传统语言中this关键字是可以省略的。但是上面的例子中:objgetP=function(){alert(thisp)表面上this指针指向的是obj}这里的this关键字是不可省略的即不能写成alert(p)的形式。这将使得getP函数去引用上下文环境中的p变量而不是obj的属性。类的实现理解类的实现机制在前面已经讲过在JavaScript中可以使用function关键字来定义一个“类”。现在介绍如何为类添加成员。其过程很简单在函数内通过this指针引用的变量或者方法都会成为类的成员例如:functionclass(){vars=”abc”PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcnthisp=sthismethod=function(){alert(“thisisatestmethod”)}}varobj=newclass()当通过newclass()获得对象obj时这个对象便自动获得了属性p和方法method。在JavaScript中function本身的定义就是类的构造函数结合前面介绍过的对象的性质以及new操作符的用法下面来看使用new创建对象的过程。()当解释器遇到new操作符时便创建一个空对象()开始运行class这个函数并将其中的this指针都指向这个新建的对象()因为当给对象不存在的属性赋值时解释器就会为对象创建该属性例如在class中当执行到thisp=s这条语句时就会添加一个属性p并把变量s的值赋给它这样函数执行就是初始化这个对象的过程即实现构造函数的作用()当函数执行完后new操作符就返回初始化后的对象。通过这整个过程JavaScript中就实现了面向对象的基本机制。由此可见在JavaScript中function的定义实际上就是实现一个对象的构造器是通过函数来完成的。这种方式的缺点是:l将所有的初始化语句、成员定义都放到一起代码逻辑不够清晰要实现复杂的功能时往往力不从心。l因为每创建一个类的实例都要执行一次构造函数。所以实际上构造函数中定义的属性和方法总被重复的创建例如:thismethod=function(){alert(“thisisatestmethod”)}这里的method每创建一个class的实例都会被创建一次造成了内存的浪费。下面一节将介绍另外一种类定义的机制:prototype对象可以解决构造函数中定义类成员带来的缺点。使用prototype对象定义类成员上一节介绍了类的实现机制以及构造函数的实现现在介绍另一种为类添加成员的机制:prototype对象。当new一个function时该对象的成员将自动赋给所创建的对象例如:<scriptlanguage="JavaScript"type="textjavascript"><!定义一个只有一个属性prop的类functionclass(){thisprop=}使用函数的prototype属性给类定义新成员classprototypeshowProp=function(){alert(thisprop)}创建class的一个实例varobj=newclass()调用通过prototype原型对象定义的showProp方法objshowProp()PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcn><script>因为prototype是一个JavaScript对象所以可以为prototype对象添加、修改、删除方法和属性。从而为一个类添加成员定义。了解了函数的prototype对象现在再来看new的执行过程。()创建一个新的对象并让this指针指向它()将函数的prototype对象的所有成员都赋给这个新对象()执行函数体对这个对象进行初始化的操作()返回()中创建的对象。和上一节介绍的new的执行过程相比现在是多了用prototype来初始化对象的过程这也和prototype的字面意思相符它是所对应类的实例的原型。这个初始化过程发生在函数体(构造器)执行之前所以可以在函数体内部调用prototype中定义的属性和方法例如:<scriptlanguage="JavaScript"type="textjavascript"><!定义一个只有一个属性prop的类functionclass(){thisprop=thisshowProp()}使用函数的prototype属性给类定义新成员classprototypeshowProp=function(){alert(thisprop)}创建class的一个实例varobj=newclass()><script>和上一段代码相比这里在class的内部调用了prototype中定义的方法showProp从而在对象的构造过程中就弹出了对话框显示prop属性的值为。需要注意原型对象的定义必须在创建类实例的语句之前否则它将不会起作用例如:<scriptlanguage="JavaScript"type="textjavascript"><!定义一个只有一个属性prop的类functionclass(){thisprop=thisshowProp()}创建class的一个实例varobj=newclass()在创建实例的语句之后使用函数的prototype属性给类定义新成员只会对后面创建的对象有效classprototypeshowProp=function(){alert(thisprop)}><script>这段代码将会产生运行时错误显示对象没有showProp方法就是因为该方法的定义是在实例化一个类的语句之后。由此可见prototype对象专用于设计类的成员它是和一个类紧密相关的除此之外prototype还有一个重要的属性:constructor表示对该构造函数的引用例如:PDF文件使用"pdfFactory"试用版本创建àwwwfineprintcnfunctionclass(){alert()}classprototypeconstructor()调用类的构造函数这段代码运行后将会出现对话框在上面显示文字“”从而更容易看出一个prototype是和一个类的定义紧密相关的。实际上:classprototypeconstructor===class。一种JavaScript类的设计模式尽管前面介绍了如何定义一个类如何初始化一个类的实例但既可以在function定义的函数体中添加成员又可以用prototype定义类的成员代码显的很混乱和面向对象语言类的实现之间有着很大的区别。那么如何以一种清晰的方式来定义类呢?下面给出了一种类的实现模式并将它们对应到面向对象语言类的实现上。类的构造函数用来初始化一个实例是每个类必不可少的一部分。在传统意义的面向对象中类的构造函数的名称和类的名称一致同时它们的定义方式和类成员的定义是类似而又相互独立的。而在JavaScript中由于对象的灵活的性质在构造函数中也可以为类添加成员在增加灵活性的同时也增加了代码的复杂度。为了提高代码的可读性和开发效率完全可以抛弃这种定义成员的方式而使用prototype对象来替代这样function的定义就是类的构造函数符合传统意义类的实现:类名和构造函数名是相

类似资料

编辑推荐

【公共行政与公共管理经典译丛】公共组织理论(第三版).pdf

四库全书总目提要-集部.doc

YYT 0340-2009.pdf

超级短线1.pdf

新概念英语教师用书新版2-实践与进步.pdf

职业精品

精彩专题

上传我的资料

精选资料

热门资料排行换一换

  • 《山海经》中华经典藏书.中华书局…

  • 道教养生故事.pdf

  • 1938年毛泽东为扳倒王明向莫斯…

  • Anti-Oedipus.pdf

  • 黄俊杰 儒学与现代台湾.pdf

  • [中华文库]画境文心:中国古典园…

  • 投资者的未来(免费完整版).doc

  • 地理寻龙点穴法诀(全).pdf

  • 我思故我笑 哲学的幽默一面.pdf

  • 资料评价:

    / 56
    所需积分:1 立即下载

    意见
    反馈

    返回
    顶部