JS模拟类继承
//最后一个参数是JSON表示的类定义
//如果参数大于一,则第一个参数是基类,否则,基类是object
//中间的参数是类实现的接口
//返回值是类,类是一个构造函数,并继承了基类的prototype
function Class(){
aDefine = arguments[arguments.length - 1]; //传入的最后一个参数是要定义的类
if(!aDefine) return; //如果没用传参数,则直接结束。
var aBase = arguments.length>1?arguments[0]:object; //如果传的参数大于1,则第一个参数为基类,若等于1,则基类默认为object
function prototype_(){}; //创建prototype临时函数,用以挂接原型链
prototype_.prototype = aBase.prototype;
var aPrototype = new prototype_(); //建立类要使用的原型对象
for(var member in aDefine){
if(aDefine[member] != ‘Create‘){ //构造函数不用挂在原型链上,构造函数是最终返回的
aPrototype[member] = aDefine[member];
}
}
//设置类
if(aDefine.Create){ //如果有构造函数
var aType = aDefine.Create; //类即为该构造函数
}else{ //如果没有构造函数
var aType = function(){ //创建默认的构造函数
this.base.apply(this, arguments); //调用父类的构造函数
}
}
aType.prototype = aPrototype; //设置类(构造函数)的原型
aType.Base = aBase; //设置类型关系
aType.prototype.Type = aType; //为本类对象扩展一个Type属性,用以判断对象的类型
return aType; //将加了原型继承的构造函数返回,就可以new了
}
function object(){}; //定义object根类,用以实现最基础的方法和属性
object.prototype.isA = function(type){ //判断对象属性是否属于某种类型
var self = this.Type;
while(self){
if(self == type){
return true;
}
self = self.Base;
}
return false;
}
object.prototype.base = function(){ //调用基类的构造函数
var Caller = object.prototype.base.caller; //得到调用该函数的函数
Caller && Caller.Base && Caller.Base.apply(this, arguments);
//如果Caller存在并且 Caller.Base存在,则调用 Caller.Base方法
//若果如果Caller或Caller.Base有一个不存在,那么后面的语句不用再执行。
}
var people = Class({ //定义people类
Create: function(name, age){
this.base();
this.name = name;
this.age = age;
},
say: function(){
console.log(‘My name is ‘ + this.name + ",I‘m " + this.age + ‘.‘);
}
})
var chinaPeople = Class(people,
{
Create: function(name, age, country){
this.base(name, age);
this.country = country;
},
sayCountry: function(){
console.log(‘My country is ‘ + this.country);
}
}
)
var man1 = new people(‘kaka‘, 32);
var man2 = new chinaPeople(‘kaka‘, 32, ‘china‘);
man2.say(); //My name is kaka,I‘m 32.
man2.sayCountry(); //My country is china
caller不支持opera浏览器,所以重写base方法
object.prototype.base = function(){
var Base = this.Type.Base; //获取当前对象的基类
if(!Base.Base){ //如果已经没有基类
Base.apply(this, arguments); //直接调用基类构造函数
}else{
this.base = MakeBase(Base); //先复写this.base
Base.apply(this, arguments);
delete this.base; //删除复写的base属性
};
function MakeBase(Type){
var Base = Type.Base;
if(!Type.Base) return Base //基类已无基类,就无需包装
return function(){ //包装为引用临时变量Base的闭包函数
this.base = MakeBase(Base); //先复写this.base
Base.apply(this, arguments); //在调用基类构造函数
}
}
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。