静态类不能通过关键字new 来创建实例,类本身是一个闭包{};内可以定义属性和方法。如:
var StaticClass = {
name:"zhangsan",
age:14,
sayhello:function(){
return "Hello," + this.name + "are you "+this.age + " ?";
}
};
alert(StaticClass.sayhello());
静态类采用json格式实现,采用类名.属性和类名.方法的方式访问其成员,类似于java中对静态属性和静态方法的访问,故我将之称为javascript静态类的实现方式。
2:非静态来的实现
function Mapper(index,param){
this.index = index||"defautIndex";
this.param = param||"defaultparam";
};
function _initializeByArray(array){
this.index = array[0];
this.param = array[1];
return this;
}
function _initializeByJson(json){
this.index = json.index||json['index'];
this.param = json.param||json['param'];
return this;
}
function _getIndex(){
return this.index;
}
function _getParam(){
return this.param;
}
Mapper.prototype.initializeByArray = _initializeByArray;
Mapper.prototype.initializeByJson = _initializeByJson;
Mapper.prototype.getIndex = _getIndex;
Mapper.prototype.getParam = _getParam;
var x = new Mapper(1,"xxx");
alert(x.getIndex()+" is "+x.getParam());
var array = [2,"yyy"];
var y = new Mapper().initializeByArray(array);
alert(y.getIndex()+" is " +y.getParam());
var json = {index:3,param:"zzz"};
var z = new Mapper().initializeByJson(json);
alert(z.getIndex() + " is " + z.getParam());
可以通过关键字new 创建实例,类本事是一个function,但是类不能提供静态方法。类成员的定义要用关键字this,而不是var。
3:非静态类的原型prototype
prototype是javascript中Function的属性,提供了类似原型的实现方式。 prototype的所有属性或方法被类的所有对象共享,修改prototype会影响其所有实例,类似于java的static声明效果。
观察类的方法可以发现,方法并没有放在类体中,而是指定给类的prototype,因此无论创建多少类的实例,这几个方法在内存中都只有一份,被所有的实例引用。这是因为对于大部分类的实例而已,他们拥有的属性是各不相同的,而调用的方法是相同的。
3:非静态类继承的实现1)父类构造方法的调用
function MenuMapper(){
Mapper.apply(this,arguments);
}
通过调用父类的构造方法,来实现自身实例化的过程。apply()方法接受两个参数,第一个object,指定在方法Mapper(类的实现本身是方法)调用时this所引用的对象,在javascript和java中this的使用方法是有区别的。第二个参数是参数数组,将传递给Mapper()方法来完成类的创建。类似的方法还有call(),call接受的第一个参数和apply相同,但是后面接受不定长参数,而不是参数数组。
2)父类属性及方法的拷贝
如果仅仅是按照上面的方式来实现继承,会使类丢失很多属性和方法。在prototype中指定的属性和方法并没有被拷贝到子类中,所以我们要完成这些工作。
MenuMapper.prototype = new Mapper();
MenuMapper.prototype.constructor = MenuMapper;
第一行用一个父类的实例作为子类的原型,同时指定构造方法名。
也可以删除某个属性,如delete Mapper.prototype.属性/方法名。当实现继承时可以如此去掉不需要的父类属性。
当完成以上工作时,我们就可以使用子类了:
var x = new MenuMapper(1,"xxx");
alert(x.getIndex()+" is "+x.getParam());
var array = [2,"yyy"];
var y = new MenuMapper().initializeByArray(array);
alert(y.getIndex()+" is " +y.getParam());
var json = {index:3,param:"zzz"};
var z = new MenuMapper().initializeByJson(json);
alert(z.getIndex() + " is " + z.getParam());