JavaScript定义类定义属性定义方法的几种方式详解及分析.doc_第1页
JavaScript定义类定义属性定义方法的几种方式详解及分析.doc_第2页
JavaScript定义类定义属性定义方法的几种方式详解及分析.doc_第3页
JavaScript定义类定义属性定义方法的几种方式详解及分析.doc_第4页
JavaScript定义类定义属性定义方法的几种方式详解及分析.doc_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JavaScript 定义类,定义属性,定义方法的几种方式详解及分析提起面向对象我们就能想到类,对象,封装,继承,多态。在javaScript高级程序设计(人民邮电出版社,曹力、张欣译。英文名字是:Professional JavaScript for Web Developers)这本书中描述的还算比较详细。我们看看JavaScript中定义类的各种方法。1工厂方式 javaScript中创建自己的类和对象,我们应该是必须掌握的,我们都知道javaScript中对象的属性可以在对象创建后动态定义,比如下面的代码: /定义 var oCar = new Object(); oCar.color = red; oCar.doors = 4; oCar.showColor = function() alert(this.color); /调用 oCar.showColor(); 我们很容易使用oCar对象,但是我们创就是想创建多个Car实例。我们可以使用一个函数来封装上面的代码来实现: /定义 function createCar() var oCar = new Object(); oCar.color = red; oCar.doors = 4; oCar.showColor = function() alert(this.color); return oCar; /调用 var ocar1 = createCar(); var ocar2 = createCar(); ocar1.color = black; ocar1.showColor(); ocar2.showColor(); 顺便说一下,javaScript对象默认成员属性都是public 的。这种方式我们称为工厂方式,我们创造了能创建并返回特定类型的对象的工厂。 这样做有点意思了,但是在面向对象中我们经常使用创建对象的方法是:Car car=new Car(); 使用new 关键字已经深入人心,因此我们使用上面的方法去定义总感觉别扭,并且每次调用时都去创建新的属性以及函数,功能上也不实际。下来我们看看构造函数的形式定义类。2构造函数这种方式看起来有点象工厂函数。具体表现如下: /定义 function Car(color, doors) this.color = color; this.doors = doors; this.showColor = function() alert(this.color); ; /调用 var car1 = new Car(red, 4); var car2 = new Car(blue, 4); car1.showColor(); car2.showColor(); 看起来效果很明显,有差别了吧。感觉有点意思了。在构造函数内部创造对象使用this 关键字,使用new 运算符创建对象感觉非常亲切。但是也有点问题:每次new 对象时都会创建所有的属性,包括函数的创建,也就是说多个对象完全独立,我们定义类的目的就是为了共享方法以及数据,但是car1对象与car2对象都是各自独立的属性与函数,最起码我们应该共享方法。这就是原形方式的优势所在。3原型方式利用对象的prototype属性,可把它看出创建新对象所依赖的原型。方法如下: /定义 function Car() ; Ctotype.color = red; Ctotype.doors = 4; Ctotype.drivers = new Array(Tom, Jerry); Ctotype.showColor = function() alert(this.color); /调用: var car1 = new Car(); var car2 = new Car(); car1.showColor(); car2.showColor(); alert(car1.drivers); car1.drivers.push(stephen); alert(car1.drivers); /结果:Tom,Jerry,stephen alert(car2.drivers); /结果:Tom,Jerry,stephen/可以用json方式简化prototype的定义: Ctotype = color: red, doors: 4, drivers: Tom, Jerry,safdad, showColor: function() alert(this.color); 首先这段代码的构造函数,其中没有任何代码,接下来通过对象的prototype属性添加属性定义Car对象的属性。这种方法很好,但是问题是Car的对象指向的是Array指针,Car的两个对象都指向同一个Array数组,其中一个对象car1改变属性对象的引用(数组Array)时,另一个对象car2也同时改变,这是不允许的。 同时该问题也表现在原型不能带任何初始化参数,导致构造函数无法正常初始化。这需要另一种方式来解决:那就是混合的构造函数/原型模式。4. 混合的构造函数/原型模式联合使用构造函数和原型方式,定义类就非常方便。/定义 function Car(color,doors) this.color=color; this.doors=doors; this.drivers=new Array(Tom,Jerry); Ctotype.showColor=function() alert(this.color); /调用: var car1=new Car(red,4); var car2=new Car(blue,4); car1.showColor(); car2.showColor(); alert(car1.drivers); car1.drivers.push(stephen); alert(car1.drivers); /结果:Tom,Jerry,stephen alert(car2.drivers); /结果:Tom,Jerry alert(car1 instanceof Car); 该方法是把属性放在内部定义,把方法放在外边利用prototype进行定义。解决了第三种方法的问题。 这种方法其实应该来说非常友好了,但是比起java的语法来,应该有一些不和谐,感觉比较凌乱,对C+来说,我们就没有那么麻烦的感觉了,可是开发C+的研发人员一般情况下很少涉及javaScript,而对J2EE的研发人员来说,这种方式总有一些别扭。总感觉不是友好的封装,其实只不过是视觉上封装效果不是很好而已,要想达到视觉封装效果而又能达到这种方法的效果的也可以,个人认为其实比较麻烦。那就是动态原型法。5.动态原型对于习惯使用其他语言的开发者来说,使用混合的构造函数/原型方式感觉不那么和谐。毕竟,定义类时,大多数面向对象语言都对属性和方法进行了视觉上的封装。考虑下面的C#类:class Car /class public string color = red; public int doors = 4; public int mpg = 23; public Car(string color, int doors, int mpg) /constructor this.color = color; this.doors = doors; this.mpg = mpg; public void showColor() /method Console.WriteLine(this.color); C#很好的打包了Car类的所有属性和方法,因此看见这段代码就知道它要实现什么功能,它定义了一个对象的信息。批评混合的构造函数/原型方式的人认为,在构造函数内存找属性,在其外部找方法的做法不合逻辑。因此,他们设计了动态原型方法,以提供更友好的编码风格。动态原型方法的基本想法与混合的构造函数/原型方式相同,即在构造函数内定义非函数属性,而函数属性则利用原型属性定义。唯一的区别是赋予对象方法的位置。下面是用动态原型方法重写的Car类: /定义 function Car() this.color = red; this.doors = 4; this.drivers = new Array(Tom, Jerry); if (typeof Car._initialized = undefined) Ctotype.showColor = function() alert(this.color); /. /最后定义 Car._initialized = true; 直到检查typeof Car._initialized是否等于undefined之前,这个构造函数都未发生变化。这行代码是动态原型方法中最重要的部分。如果这个值未定义,构造函数将用原型方式继续定义对象的方法,然后把Car._initialized设置为true。如果这个值定义了(它的值为true时,typeof的值为Boolean),那么就不再创建该方法。简而言之,该方法使用标志(_initialized)来判断是否已给原型赋予了任何方法。该方法只创建并赋值一次,为取悦传统的OOP开发者,这段代码看起来更像其他语言中的类定义了。6 混合工厂方式这种方式通常是在不能应用前一种方式时的变通方法。它的目的是创建假构造函数,只返回另一种对象的新实例。这段代码看来与工厂函数非常相似:function Car() var oTempCar = new Object(); oTempCar.color=red; oTempCar.doors=4; oTempCar.mpg=23; oTempCar.showColor = function() alert(this.color); return oTempCar; 与经典方式不同,这种方式使用new运算符,使它看起来像真正的构造函数:var oCar = new Car();由于在Car()构造函数内部调用了new运算符,所以将忽略第二个new运算符(位于构造函数之外)。在构造函数内部创建的对象被传递回变量var。这种方式在对象方法的内部管理方面与经典方式有着相同的问题。强烈建议:除非万不得已(请参阅第15章),还是避免使用这种方式。总结:(采用哪种方式)目前使用最广泛的是混合的构造函数/原型方式。此外,动态原型方法也很流行,在功能上与构造函数/原型方式等价。可以采用这两种方式中的任何一种。不过不要单独使用经典的构造函数或原型方式,因为这样会给代码引入问题。/ps/static class (1:function) var CarCollection = new function() var _

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论