面向对象的JavaScript开发

本文介绍了一种在JavaScript中实现面向对象编程的新方法,包括类的定义、实例化、继承及方法覆盖等内容,使得JavaScript的面向对象编程更加直观。

JavaScript作为一种脚本开发语言,由于其语法简洁灵活,功能强大,已经被开发人员广为接受。虽然JavaScript 支持面向对象开发(OOP),但与我们通常所熟悉的面向对象开发语言,如Java、C++等,在类和对象的语法定义上有很大的区别,在Java、C++等面向对象的开发语言中定义类和对象非常直观,如在Java语言中定义类:

public class  A
{
    
//属性定义
    private String str;
    
private int i;

    
//方法定义
    public void test() {
        System.out.println(
"test");
    }

}


//定义实例对象
A a = new A();

而在JavaScript中类的定义与一般函数的定义是一样的:


function A() {
    
//属性定义
    this.str = "test";
    
this.i = 0;
}

//方法定义
A.prototype.test = function() {
    alert(
this.str);
}


//对象实例定义
var a = new A();
a.test();

在表现形式上不太直观,而且容易让人与一般功能函数产生混淆。

 笔者根据平时的一点开发经验和体会,在现有JavaScript语法的基础上,向大家介绍一种更直观的类定义方法。

一、JxObject类

为了支持新的类定义形式,笔者先定义了一个JxObject类来提供一些必要的方法支持,其代码如下:

/******************************
 * JxObject.js
 * created on 2007-04-23
 ******************************
*/


//
//
--- JxObject class ----------------------------------
//
function JxObject() {

}


//类定义方法
JxObject.defineClass = function(clsBody) {
    
var cls = new Function();
    cls.prototype 
= (new JxObject()).extended(clsBody);
    cls.__getInstance 
= function() 
        
return new cls();
    }
;
    cls.getInstance 
= function() 
        
var newObj = cls.__getInstance();
        
if(newObj.init != null && typeof newObj.init == 'function'{
            newObj.init.apply(newObj, arguments);
        }

        
return newObj;
    }
;
    
var __superTargetObj = cls.__getInstance();
    cls.__getSuperTargetObj 
= function() return __superTargetObj; };
    
return cls;
}


//类继承方法
JxObject.inherits = function(targetCls, clsBody) {

    
var targetObj = targetCls.__getInstance();

    targetObj.__super 
= function(__superClass, fname) {
        
var __superObj = __superClass.__getSuperTargetObj();
        
if(typeof __superObj[fname] != 'undefined' && __superObj[fname] != null
            
&& typeof __superObj[fname] == 'function'{
            
var args = new Array();
            
for(var i=2; i<arguments.length; i++{
                args[i
-2= arguments[i];
            }

            
return __superObj[fname].apply(this, args);
        }

    }
;

    
var cls = JxObject.defineClass(clsBody);
    cls.prototype 
= targetObj.extended(clsBody);
    
return cls;
}


JxObject.prototype.extended 
= function(targetObj) {
    
return JxObject.__extends.apply(this, [this, targetObj]);
}


JxObject.__extends 
= function(targetObj, parentObj) {
    
for(var i in parentObj) {
        targetObj[i] 
= parentObj[i];
    }

    
return targetObj;
}


在JxObject类中定义了两个非常重要的方法:defineClass和inherits,对于这两个方法的使用将在下面逐一介绍。

二、类的定义

有了JxObject类中的defineClass方法的支持,我们可以在JavaScript中这样来定义类:

var Person = JxObject.defineClass({
    
//属性定义
    name : "",
    age : 
0,
    
    
//方法定义
    init : function(name, age) {
        
this.name = name;
        
this.age = age;
    },
    sayHello : 
function() {
        alert(
"Hello, I'm " + this.name + ", my age is " + this.age + ". "
            
+ "And I'm so glad to know you!");
    }
});


var mike = Person.getInstance('Mike'20);
mike.sayHello();
var jack = Person.getInstance('Jack'30);
jack.sayHello();

 从上例中我们可以看到,defineClass方法的参数为一个临时对象,用来包含当前要定义的类的方法和属性,通过这样的定义形式,类的定义变得比较直观了,类的实例变量不再需要用new操作符来生成,而是通过调用在类中定义的getInstance方法来生成,而且,如果需要对实例变量进行初始化,只需要在类的定义中定义一个init(arg1,arg2,...)方法就可以了,当通过调用getInstance方法获得类的实例变量时,该方法将被自动调用。

 三、类的继承

在前面的例子中,我们看到了类定义的方法,现在让我们来看看怎样从现有的类继承产生子类,先看下面的例子:

var Person = JxObject.defineClass({

    name : 
"",
    age : 
0,
    
    init : 
function(name, age) {
        
this.name = name;
        
this.age = age;
    }
,
    
    sayHello : 
function() {
        alert(
"Person: name=" + this.name + ", age=" + this.age);
    }

}
);


//从Person类继承生成Chinese类
var Chinese = JxObject.inherits(Person, {

    addr : 
"",
    
    init : 
function(name, age, addr) {
        
this.addr = addr;
        
this.__super(Person, 'init', name, age); //调用父类Person类的init方法
    }
,
    
    
//覆写父类Person类的sayHello方法
    sayHello : function() {
        alert(
"你好,我叫" + this.name + ",我今年" + this.age + "岁。 "
            
+ "我来自" + this.addr + " "
            
+ "很高兴认识你!");
    }
,
    
    parentHello : 
function() {
        alert(
'调用父类 sayHello()方法');
        
this.__super(Person, 'sayHello');
    }

}
);


//从Person类继承生成American类
var American = JxObject.inherits(Person, {
    
//覆写父类Person类的sayHello方法
    sayHello : function() {
        alert(
"Hello, I'm " + this.name + ", my age is " + this.age + ". "
            
+ "And I'm so glad to know you!");
    }

}
);


function hello(person) {
    
if(person instanceof Person) {
        person.sayHello();
    }
else {
        alert(
"Not Person object");
    }

}


var xw = Chinese.getInstance('小王'30'湖北武汉');
var mike = American.getInstance('Mike'20);

function test() {
    hello(xw);
    hello(mike);
    hello(
"non");
    xw.parentHello();
}

 从上面的例子中,我们可以看到类的继承变得很直观了,inherits方法的第一个参数是要继承的父类,第二个参数与defineClass中的一样。通过inherits方法继承的子类,可以在子类中通过类定义的__super方法来调用父类的方法,在子类中还可以覆写父类方法。

四、总结

 通过上面介绍的方法,我们现在可以比较直观地利用JavaScript来定义类了,而且我们可以在程序的任何地方来定义类及生成类的实例,如我们可以在函数内部定义类及生成类的实例:


function test(name, age) {

    
return JxObject.defineClass({

        name : 
"",
        age : 
0,
    
        init : 
function(name, age) {
            
this.name = name;
            
this.age = age;
        },
        
        sayHello : 
function() {
            alert(
"Person: name=" + this.name + ", age=" + this.age);
        }
    }).getInstance(name, age);

}

var p = test('test'100);
p.sayHello();

以上就是笔者对JavaScript面向对象开发的一点经验,拿出来与各位读者交流探讨。

另:笔者自己已经利用上面介绍的方法开发了一个控件库,其中包括菜单、树形控件、标签控件等,以后会发到网上来与大家共享。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值