深圳医院网站建设,WordPress最好用编辑器,设计网站如何推广,wordpress可视化菜单1#xff0e;工厂方式javaScript中创建自己的类和对象#xff0c;我们应该是必须掌握的#xff0c;我们都知道javaScript中对象的属性可以在对象创建后动态定义#xff0c;比如下面的代码#xff1a;script typetext/javascript//定义var oCar new O… 1工厂方式 javaScript中创建自己的类和对象我们应该是必须掌握的我们都知道javaScript中对象的属性可以在对象创建后动态定义比如下面的代码 script typetext/javascript //定义 var oCar new Object(); oCar.color red; oCar.doors 4; oCar.showColor function() { alert(this.color); } //调用 oCar.showColor();/script 我们很容易使用oCar对象但是我们创就是想创建多个Car实例。我们可以使用一个函数来封装上面的代码来实现script typetext/javascript //定义 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();/script 顺便说一下javaScript对象默认成员属性都是public 的。这种方式我们称为工厂方式我们创造了能创建并返回特定类型的对象的工厂。 这样做有点意思了但是在面向对象中我们经常使用创建对象的方法是 Car carnew Car(); 使用new 关键字已经深入人心因此我们使用上面的方法去定义总感觉别扭并且每次调用时都去创建新的属性以及函数功能上也不实际。下来我们看看构造函数的形式定义类。 2构造函数 这种方式看起来有点象工厂函数。具体表现如下 script typetext/javascript //定义 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();/script 看起来效果很明显有差别了吧。感觉有点意思了。在构造函数内部创造对象使用this 关键字使用new 运算符创建对象感觉非常亲切。但是也有点问题每次new 对象时都会创建所有的属性包括函数的创建也就是说多个对象完全独立我们定义类的目的就是为了共享方法以及数据但是car1对象与car2对象都是各自独立的属性与函数最起码我们应该共享方法。这就是原形方式的优势所在。 3原型方式 利用对象的prototype属性可把它看出创建新对象所依赖的原型。方法如下 script typetext/javascript //定义 function Car() { }; Car.prototype.color red; Car.prototype.doors 4; Car.prototype.drivers new Array(Tom, Jerry); Car.prototype.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的定义: Car.prototype { color: red, doors: 4, drivers: [Tom, Jerry,safdad], showColor: function() { alert(this.color); } }/script 首先这段代码的构造函数其中没有任何代码接下来通过对象的prototype属性添加属性定义Car对象的属性。这种方法很好但是问题是Car的对象指向的是Array指针Car的两个对象都指向同一个Array数组其中一个对象car1改变属性对象的引用数组Array时另一个对象car2也同时改变这是不允许的。 同时该问题也表现在原型不能带任何初始化参数导致构造函数无法正常初始化。这需要另一种方式来解决那就是混合的构造函数/原型模式。 4. 混合的构造函数/原型模式 联合使用构造函数和原型方式定义类就非常方便。 script typetext/javascript//定义 function Car(color,doors) { this.colorcolor; this.doorsdoors; this.driversnew Array(Tom,Jerry); } Car.prototype.showColorfunction(){ alert(this.color); } //调用 var car1new Car(red,4); var car2new 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); /script 该方法是把属性放在内部定义把方法放在外边利用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类 script typetext/javascript //定义 function Car() { this.color red; this.doors 4; this.drivers new Array(Tom, Jerry); if (typeof Car._initialized undefined) { Car.prototype.showColor function() { alert(this.color); } //............ } //最后定义 Car._initialized true; } /script 直到检查typeof Car._initialized是否等于undefined之前这个构造函数都未发生变化。这行代码是动态原型方法中最重要的部分。如果这个值未定义构造函数将用原型方式继续定义对象的方法然后把Car._initialized设置为true。如果这个值定义了它的值为true时typeof的值为Boolean那么就不再创建该方法。简而言之该方法使用标志_initialized来判断是否已给原型赋予了任何方法。该方法只创建并赋值一次为取悦传统的OOP开发者这段代码看起来更像其他语言中的类定义了。 6 混合工厂方式 这种方式通常是在不能应用前一种方式时的变通方法。它的目的是创建假构造函数只返回另一种对象的新实例。这段代码看来与工厂函数非常相似 function Car() { var oTempCar new Object(); oTempCar.colorred; oTempCar.doors4; oTempCar.mpg23; 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 _carCollection new Array(); //global,private this.Add function(objCar) { alert(Add); } this.Get function(carid) { alert(Get); } } //static class (2:json) var Car { color: red, doors: 4, showColor: function() { alert(this.color); } } Car.showColor(); 本文来自CSDN博客转载请标明出处http://blog.csdn.net/avon520/archive/2009/01/17/3819751.aspx 转载于:https://blog.51cto.com/fluagen/303152