纵观方今天下,Web已然大势所趋,JavaScript地位彰显,VB、Delphi等逐渐淡出。但是,VB的事件机制使用起来确实很方便。下面,我们将在JavaScript中模拟这种事件机制,并就JavaScript的面向对象编程做些实践应用。
目前JavaScript还不是纯正的面向对象语言,而是一种基于对象的语言。本文对其面向对象的一些概念不作探讨,而将主要精力集中于其对面向对象特性的实现上。
为了方便演示,我们将在一个DIV中输出程序的运行状态。为此,自定义了一个Print()函数和一个Clear()函数,顾名思义,其分别用于打印和清屏。本文的源码请参考附录部分。
(C)ShiShengSoft原创文章,转载请注明出处:http://blog.youkuaiyun.com/shishengsoft/
一、类的封装
在JavaScript中有几种类的封装形式,我们通过建立若干种动物类来加以说明。
// ************************************************************************************
// 类的封装:属性、方法、事件
// ************************************************************************************
// 雄鹰
// ************************************************************************************
function Tercel(sName,iMaxAge){
this.Age = 0;
this.MaxAge = iMaxAge;
this.Name = sName;
this.pullulate = pullulate;
this.Dead = function(){};
}
function pullulate(){
Print("雄鹰在成长...<br>");
while (this.Age<=this.MaxAge){
Print((this.Age++) + "<br>");
}
this.Dead();
}
// ************************************************************************************
// 使用示例
// ************************************************************************************
function btnTercel::onclick(){
Clear();
var MyTercel = new Tercel("雄鹰",40);
MyTercel.Dead = function(){
Print(MyTercel.Name + "生命结束.<br>");
}
MyTercel.pullulate();
}
// ************************************************************************************
首先,用new Tercel("雄鹰",40)创建一个MyTercel对象,同时指定了它的Name属性和MaxAge属性的值。
接着,为MyTercel.Dead事件指定一个执行函数,以便MyTercel生命结束时显示其状态。
然后,通过调用MyTercel.pullulate()方法,我们便能观察到它的成长过程。
在pullulate()方法中,我们用一个while循环来使MyTercel的Age属性值不断增加,
当Age大于MaxAge时,MyTercel的生命就结束了,此时就会触发Dead()事件,这样,我们为MyTercel对象指定的函数就会执行。
// ************************************************************************************
// 野兔
// ************************************************************************************
function Hare(sName,iMaxAge){
this.MaxAge = iMaxAge;
this.Name = sName;
}
Hare.prototype.Age = 0;
Hare.prototype.pullulate = function(){
Print("野兔在成长...<br>");
while (this.Age<=this.MaxAge){
Print((this.Age++) + "<br>");
}
this.Dead();
}
Hare.prototype.Dead = function(){}
// ************************************************************************************
// 鲨鱼
// ************************************************************************************
function Shark(sName,iMaxAge){
this.Age = 0;
this.MaxAge = iMaxAge;
this.Name = sName;
this.pullulate = function(){
Print("鲨鱼在成长...<br>");
while (this.Age<=this.MaxAge){
Print((this.Age++) + "<br>");
}
this.Dead();
}
this.Dead = function(){};
}
// ************************************************************************************
在雄鹰、野兔、鲨鱼三种方案中,鲨鱼的方案与其它语言中类的形式比较接近。但是,由于类的创建是以Function的形式创建的,
故不像其它语言中创建类的使用构造函数和析构函数。不过我们可以用如下办法模拟。
function Shark(){
this.Create = function(){};
this.Destroy = function(){};
}
通过编写一个没有参数的Shark()类,再编写Create和Destory两个函数分别用于构造和析构,在实例化时显示的调用即可。
二、类的继承与多重继承
在这节中,我们将创建一个Animal类作为其它动物类的基类,并使用一个jsTimer定时器对象来控制各个动物的成长过程。
// ************************************************************************************
// 类的继承
// ************************************************************************************
// 动物〔基类〕
// ************************************************************************************
function Animal(sName){
var m_iAge, m_iMaxAge;
var m_DeadFunc, m_pullulateFunc;
this.Age = 0;
this.MaxAge = 0;
this.Name = sName;
this.Create = function(){
m_iAge = this.Age;
m_iMaxAge = this.MaxAge;
m_DeadFunc = this.Dead;
m_pullulateFunc = this.pullulate;
MyTimer.setEnable(true);
Print(this.Name + "诞生.<br>");
}
this.Dead = function(){};
this.pullulate = function(){};
var MyTimer = new jsTimer(100);
MyTimer.TimerEvent = function(){
if ((++m_iAge) > m_iMaxAge){
MyTimer.setEnable(false);
m_DeadFunc(); //死亡事件
}
else{
m_pullulateFunc(m_iAge);//成长事件
}
}
}
// ************************************************************************************
// 鲸鱼
// ************************************************************************************
function Whale(sName,iMaxAge){
this.Inherit = Animal;
this.Inherit();
delete this.Inherit;
//Animal.call(this);
this.Name = sName;
this.MaxAge = iMaxAge;
this.Swim = function(){
Print(this.Name + "在海里游动.<br>");
}
}
// ************************************************************************************
// 天鹅
// ************************************************************************************
function Swan(sName,iMaxAge){
//Animal.call(this);
this.Name = sName;
this.MaxAge = iMaxAge;
this.Fly = function(){
Print(this.Name + "在天空飞翔.<br>");
}
}
Swan.prototype = new Animal("飞禽");
// ************************************************************************************
// 多重继承
// ************************************************************************************
function Roc(sName,iMaxAge){
Animal.call(this);
Whale.call(this);
Swan.call(this);
this.Name = sName;
this.MaxAge = iMaxAge;
}
// ************************************************************************************
1、在Whale类的,我们采用
this.Inherit = Animal;
this.Inherit();
delete this.Inherit;
来继承Animal类。注意,Inherit不是JavaScript语言中的关键字,可以取其它名字。
2、在Swan类,我们则用
Swan.prototype = new Animal();
来继承Animal类。
3、在Roc类中,则采用了
nimal.call(this);
Whale.call(this);
Swan.call(this);
的方式实现了继承和多重继承。
显然,使用call()方法是非常方便的。与call()相似的还有apply()方法。
附录:1、文章示例源码
2、自定义JavaScript定时器类