您的位置:首页 > Web前端 > JavaScript

浅谈javascript的面向对象(一)如何实现类

2008-10-25 10:11 543 查看
这里将讨论关于javascript的面向对象特点的实现,如封装,组合,继承,多态。

1.对象的声明与实例化。

var oObject=new Object();//如果构造函数中没有参数,则Object后的括号可有可无。

2.对象的销毁。

javascript中有无用存储单元收集程序,也就说不必专门设计函数来销毁对象。当对象没有被再引用时,对象使用的内存将被回收。一般把对象强制为null,可以强制释放。

3. 关于早绑定与晚绑定:

early binding:是在实例化对象之前定义它的属性与方法。这样编译器或解释程序就能提前转换机器代码。而javascript不是 强类型语言,所以不支持。

late binding: 是在编译器或解释程序运行前,不知对象的类型,使用late binding无需检查对象的类型,只要检查对象是否支持对应的属性或方法即可。javascript所有变量都采用此方法。

4.关于内置对象,只有两个Global ,Math。而Array,Function等都是本地对象。关于数据处理,下次专门讨论。

Global 其实它是不存在,如果你写 var pointer=Global 则将产生错误。这是由于在javascript中所有方法都必须是某种对象的方法。比如它有的方法:isNaN(),isFinite(),parseInt()等。

5.类的创建。

1) 原始法 .对象的属性可心服在对象创建后动态定义。所以有下面的方式:

var oCar=new Object();

oCar.color="red"; //属性

oCar.doors=4;

oCar.showColor=function()//方法

{

alert(this.color); //关键字this 用来引用对象的属性。如果改成 color将出错

}

这里意思是创建对象oCar,并给它赋予了几个属性与方法。下面就可以测试一下oCar的使用了。如oCar.showColor();//将输出 red.

这种方式的缺点:如果要创建多个对象,我想你将很头疼,因为这样只是实现一个对象的创建。很自然的我们会想到用函数把上面的方式封装起来。

2) 工厂方式。了解设计模式的都应该知道有个工厂模式,这里的意思差不多,就是批量生产对象。

改造上面的实现方式。

function createCar()

{

var oTempCar=new Object;

oTempCar.color="red";

oTempCar.doors=4;

oTempCar.showColor=function(){alert(this.color);}

return oTempCar; //这里很关键

}

这样我们就实现了多个对象创建。var oCar1=createCar(); var oCar2=createCar();上面是用函数的方式实现,是函数都能有参数,所以还可以为对象传递参数,而不是使用默认。如下:

function createCar(sColor,iDoors)

{

var oTempCar=new Object;

oTempCar.color=sColor;

oTempCar.doors=iDoors;

oTempCar.showColor=function(){alert(this.color);}

return oTempCar; //这里很关键

}

缺点:没用用new关键字来创建对象,不符合面向对象创建对象的编程习惯。还有创建一个对象就创建一个函数showColor。在资源上很浪费。也让不同的对象有了不同的showColor。可能你已经想到把函数的实现放到外面去。看一下实现:

function showColor()

{

alert(this.color);

}

function createCar(sColor,iDoors)

{

var oTempCar=new Object;

oTempCar.color=sColor;

oTempCar.doors=iDoors;

oTempCar.showColor=showColor;

return oTempCar; //这里很关键

}

这样就避免了同一函数多次创建的问题,不过还是没有像C#那样的 string str=new string();这样的东东爽吧。

3)构造函数法

function Car(sColor,iDoors)

{

this.color =sColor;

this.doors=iDoors;

this.showColor=new function(){ alert(this.color);}

}

var oCar1=new Car("red",2);

oCar1.showColor();//输出 red

这时里面没有临时对象oTempCar了吧。全用this引用。而默认情况返回的就是this。你可能会问这不又是多次创建函数了吗,没错。请看下一种方法。

4) 原形方法.此方法利用了对象的prototype属性。对上面进行如下改造:

function Car(){}

Car.prototype.color="red"; //prototype指定新对象的依赖的原型。

Car.prototype.doors=4;

Car.prototype.showColor=function(){alert(this.color);}

//test;

var oCar=new Car();

这样所有属性不会因创建多个对象而有不同的版本。此外运用此种方法,还可以用instanceof 来检查对象的类型。如: alert( oCar instanceof Car) ;//outputs "true".

遗憾的是,这个构造函数中没有参数,只能使用默认参数值,这就意味着要等对象创建后才能修改其属性的值。如果你是个聪明的人你可能已经发现,这次把函数独立出来了,可是属性也分了出来,这样不同对象的属性开始共享属性,也就是说。如果有下面的情况,我们为Car加上一个引用类型。

function Car(){}

Car.prototype.color="red"; //prototype指定新对象的依赖的原型。

Car.prototype.doors=4;

Car.prototype.drivers=new Array("china","中国");

Car.prototype.showColor=function(){alert(this.color);}

//test;

var oCar1=new Car();

var oCar2=new Car();

oCar1.push("操死小日本");

alert(oCar1.drivers);//output "china,中国,操死小日本"

alert(oCar2.drivers);//output "china,中国,操死小日本"

由于drivers是引用值,所以Car的两个实例都指向一个值。

这与真正的面向对象还是一段距离。再次进行改造。

5) 混合的构造/原形方式。

可能你已经想到,既然用prototype属性能让对象属性外置,那何不把对象的属性放在构造函数内,而把方法用prototype引用到构造函数外内。这样就可以解决所有问题了:

function Car(sColor,iDoors)

{

this.colors=sColor;

this.doors=iDoors;

this.drivers=new Array("东京大屠杀吧!");

}

Car.prototype.showColor=function()

{alert(this.color);}

var oCar1=new Car("red",4);

var oCar2=new Car("blue",4);

oCar1.drivers.push("给东京来个原子炸");

alert(oCar1.drivers)//output "东京大屠杀吧,给东京来个原子炸";

alert(oCar2.drivers)//output "给东京来个原子炸".

由于使用了原型方法,所以仍可以用instanceof来检查对象的类型,详情见上。只要是用了原型的方式实现类则可用instanceof来检查对象,而什么是原型,用了prototype的就是了。

好了到现已经差不多了吧,没有了多个函数版本造成的内存浪费问题,没有属性共享问题。和面向对象已经很接近了。但是美中不足的是函数必须要写到类之外,如果知道C++的应该知道,它可以把方法内置,也可以写在类内。写在外面让人阅读起来很费劲。所以继续改造。

6)动态原型法。它与混合的构造/原型差不多,只是函数的实现位置转到类内部。

function Car(sColor,iDoors)

{

this.colors=sColor;

this.doors=iDoors;

this.drivers=new Array("东京大屠杀吧!");

//注意这里

if(typeof Car._initialized=="true")

{

Car.prototype.showColor=function()

{alert(this.color);}

Car._initialized=true;//以_开头的属性被大家公的一种私有属性的表示方法,但是只是表示上的私有,而它是public的。

}

}

OK。到现在为止,用javascript实现类,有几种方式已经介绍完了。欢迎交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: