Javascript--定义类或对象

it2024-11-14  32

使用预定义对象的能力只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自定义的类和对象.有以下几种创建方式:

1.工厂方式

我们可以这样定义一辆车:

var car1 = new Object; car1.color='red'; car1.doors=4; car1.showColor=function(){ return this.color; } 此时,我们创建了一辆车,但是,当我们想创建第二辆,第三辆车时,该如何写呢?再写一遍类似重复的代码?不是,此时我们就可以使用工厂方式: function CreateCar(){ var car1 = new Object; car1.color='red'; car1.doors=4; car1.showColor=function(){ return this.color; } return car1; } 现在,若我们需要car,则只需要做如下操作就可以了: var car1 = CreateCar(); var car2 = CreateCar(); 此时,我们获得的车的属性都是固定的,我们还可以动态的设定车的属性,如下: function CreateCar(color,doors){ var car1 = new Object; car1.color=color; car1.doors=doors; car1.showColor=function(){ return this.color; } return car1; } 现在,我们再创建车辆时,就可以动态设置car的属性了. 但是对于上面的代码,我们发现,每当我们创建一辆车的时候,车的属性可能不同,但车的showColor方法却是一致的,而我们却每次都要创建一个相同的方法, 我们对上面的类做以下处理: function showColor(){ return this.color; } function CreateCar(color,doors){ var car1 = new Object; car1.color=color; car1.doors=doors; car1.showColor=showColor; return car1; } 此时,我们基本算是完成了对工厂方式的构建. 2.构造函数方式 创建构造函数方式和创建工厂方式一样简单,我们来看以下实例: function Car(color,doors){ this.color=color; this.doors=doors; this.showColor=function(){ return this.color; } } 我们注意到,在构造函数中,我们并没有创建对象,而是使用了关键字this,在使用new运算符创建新的对象时,在执行第一行代码前先创建一个对象, 只有用this才能访问到该对象,然后直接赋予this属性,默认情况下是构造函数的返回值. 就像工厂方式一样,构造函数方式还是会重复生成函数,尽管同样可以使用先定义函数,再引用该函数的形式,但是,这样做,在语意上并没有什么优势. 现在,我们来看原型方式. 3.原型方式 该方式利用了对象prototype属性,可把它看成是创建对象所依赖的原型.在这里,是先定义一个空的构造函数来设置类名,然后将所有的属性和方法都 定义在prototype属性上,具体见例子: function Car(){ } Car.prototype.color='red'; Car.prototype.doors=4; Car.prototype.showColor=function(){ return this.color; } 此时,我们已经定义好了一个Car类,现在,当我们使用new Car()时,原型的所有属性和方法都会被立即赋予要创建的对象,这就意味着所有的Car的实例 都存放着指向showColor()函数的指针. 原型方式有以下缺点: a.构造函数没有参数,无法在建立对象的时候就使用自定义属性. b.实例的所有属性都是被共享的,若其中一个改变,则可能会影响到其他的实例(此处的属性针对的是引用类型的属性). 针对b问题,我们来看以下代码: function Car(){ } Car.prototype.drivers = new Array("张三","李四"); var car1 = new Car(); var car2 = new Car(); car1.drivers.push("王五"); document.write(car2.drivers); 注意: 此处,我们在car1上增加了一个驾驶员,现在,我们输出的结果是car2的驾驶员.结果如何呢,让我们来看看. 我们发现,car2的驾驶员也增加了一个,从而造成了结果并非是我们预期的结果. 现在,我们使用混合的构造函数/原型方式来创建对象,就可以避免这个问题. 4.构造函数/原型方式 使用这种构造方式也很简单,主要就是:构造函数定义所有非函数的属性,原型定义所有的函数属性.结果就是所有的函数都仅仅被创建一次,而每个对象都 拥有自己的对象属性实例.见代码: function Car(color,doors){ this.color=color; this.doors=doors; this.drivers=new Array("张三","李四"); } Car.prototype.getColor=function(){ return this.color; } 5.动态原型方法 对于习惯了使用高级编程语言的人来说,定义一个类,应该是方法和属性都在类体内,而现在属性在类体内,而方法在类体外建立,感觉似乎有些不太和谐. 于是就出现了动态原型方法.动态原型方法和构造函数/原型方法的基本方法基本上相同,唯一的区别就是赋予对象方法的位置不同,见例子: function Car(color,doors){ this.color=color; this.doors=doors; this.drivers=new Array("张三","李四"); if(typeof Car._init=="undefined"){ Car.prototype.getColor=function(){ return this.color; } Car._init=true; } } 现在执行 new Car('red',4),在执行typeof Car._init=='undefined'之前,这个方法都一直在正常运行,直到这段代码,如果这个值未定义, 构造函数将用原型方式定义对象方法,然后将Car._init属性定义为true,那么再此创建实例时,Car._init属性已经为true,就不会再重新对象原型方法了. 6.混合工厂方法 混合工厂方法和工厂方式几乎一致,它同样是先构造对象,然后再往对象中添加属性和方法,唯一的区别就是混合工厂方法在生成对象的时候依旧使用new关键字. 见代码: function CreateCar(color,doors){ var car1 = new Object; car1.color=color; car1.doors=doors; car1.showColor=function(){ return this.color; }; return car1; } var c = new CreateCar('red',4); 混合工厂方法和工厂方式及经典方式(构造函数,原型方式)一样都会产生问题,了解即可,不建议使用. 以上介绍了6种构造方式,目前使用最广泛的还是构造函数/原型方式.此外,动态原型方式也很流行,在功能上和构造函数/原型方式等价. 不过不要单独使用经典的构造函数方式或者原型方式.

转载于:https://www.cnblogs.com/oneword/archive/2009/12/15/1625021.html

最新回复(0)