有没有无参构造函数的继承呢?
类似function a(){
this.show=function(){
alert("a");
}
}function b(){
this.myA=a;
delete this.myA;
}function ok(){
var myB= new b();
myB.show();
}这段代码是我自己写的不知道为什么不能运行,求大师指点!
类似function a(){
this.show=function(){
alert("a");
}
}function b(){
this.myA=a;
delete this.myA;
}function ok(){
var myB= new b();
myB.show();
}这段代码是我自己写的不知道为什么不能运行,求大师指点!
* @staticMethod clazz(className, superClass, interfaces, bodyFn) 创建一个类, Fan.clazz等价于Fan.$class
*
* @param {String} className 完整类名:Fan.test.TestCreateClass
*
* @param {Class} superClass 该类继承自指定的类,缺省时将会继承Object
*
* @param {Function} bodyFn 类是实现部分,由一个function构成
*
* 参数列表:
* className 永远占据第一个位置;
* superClass 有则占据第二个位置;
* interface 可变长度的参数列表,当有superClass时,从第三个位置开始,到倒数第二个参数为止,全部为interface;
* bodyFn 永远占据最后一个位置;
* @method clazz(className, bodyFn)
* @method clazz(className, superClass, bodyFn)
* @method clazz(className, superClass, interface, bodyFn)
* @method clazz(className, superClass, interface1, interface2, interface3, interface..., bodyFn)
* @method clazz(className, superClass, [interface1, interface2, interface3], bodyFn)
* @method clazz(className, interface, bodyFn)
*/
$class : function(cn, spc, itfs, bf){
var len = arguments.length;
if (len == 2) {
bf = spc;
spc = null;
itfs = null;
} else if (len == 3) {
bf = itfs;
if (Fan.isClass(spc) || spc === Object)
itfs = null;
else {
itfs = Fan.isArray(spc) ? spc : [spc];
spc = null;
}
} else if (len == 4){
if (Fan.isClass(spc) || spc === Object) {
if (!Fan.isArray(itfs)) itfs = [itfs];
} else {
itfs = [spc, itfs];
spc = null;
}
} else if (len > 4) {
var is = [];
if (Fan.isInterface(spc)) {
is.push(spc);
spc = null;
}
for(var i = 2, l = arguments.length - 1; i < l; ++i) {
is.push(arguments[i]);
}
bf = arguments[len - 1];
itfs = is;
} else throw new Error('Error:creating class exception, argument list error.');
spc = spc || Fan.Object; // 缺省继承Fan.Object;
itfs = itfs || null;
// 检测父类是否实现过接口,并取出
if (Fan.isClass(spc)) {
var is = spc.getInterfaces();
if (is.length > 0) {
itfs = itfs || [];
for (var i = 0, l = is.length; i < l; ++i) {
itfs.push(is[i]);
}
}
} var c = bf;
// class proxy
var cp = function(){
// 判断是否为通过new关键字调用
if (this instanceof arguments.callee){
// 构造对象,主动调用构造函数
var o = new arguments.callee[Fan.keys.FAN_CLAZZ_BODY]();
// var o = this;
var fname = Fan.fn.last(cn.split('.'));
if (Fan.isFunction(o[fname])) {
o = o[fname].apply(o, arguments) || o;
// 删除新对象中的构造方法
delete o[fname];
} else {
// 没有构造函数时,执行默认构造函数
Fan.oop.dc.apply(o, arguments);
}
return o;
} else {
arguments.callee[Fan.keys.FAN_CLAZZ_BODY].apply(this, arguments);
}
return null;
};
cp.prototype = c.prototype;
// 类的实现体
cp[Fan.keys.FAN_CLAZZ_BODY] = c;
cp.defer = cp.proxy = c.defer = c.proxy = undefined;
// 类名
cp.className = cn;
// 类特殊标识
cp[Fan.keys.IS_FAN_CLASS] = true;
// 保存类的源码
cp.srcCode = Function.prototype.toString.call(c);
// 实例均可通过getClass获得类的定义
c.prototype.getClass = (function(c){
return function(){return c;};
})(cp);
// 取出所有接口放在数组中,并去除冗余
if (itfs) {
var m = new Fan.util.Map(), t;
for (var i = 0, len = itfs.length; i < len; ++i, t = null) {
t = itfs[i];
if (!Fan.isInterface(t)) throw new Error('Error:creating interface exception, the error interface in argument list.');
m.put(t, true);
t = t.getInterfaces();
if (t.length > 0) {
for (var j = 0, l = t.length; j < l; ++j) {
m.put(t[j], true);
}
}
}
m.size() > 0 && (itfs = m.getKeySet());
m = null;
}
/**
* 指向父类的操作句柄,同时兼具父类构造方法
* 子类中第一句使用:this.$super(...);来调用父类构造函数
* 当父类和子类都定义了getA()方法时:
* 用this.$super.getA()来调用父类的方法
*
* 多层继承中,通过$super.$super获取更上一层的父级操作句柄
*/
c.prototype.$super = function(){
var sbc = this.getClass()/*arguments.callee.caller.caller*/, sbo = this, spc = sbc.superClass;
// 当父类为Object时
if (spc === Object) {
sbo.$super = {getClass:function(){return Object;}};
return;
}
// 多态,为每个子类对象都创建一个$super属性,并指向其父类对象,但Object不具备$super
// 创建一个父类对象,同时需要将不定参数arguments传入,需要用apply方法
// 因此通过代理类s,继承父类supCls,构造代理类并传入不定参数,并在代理类中通过supCls的
// apply模拟父类对象的生成,此时new出来的代理对象支持instanceof鉴别,且拥有父类所有属性
var sp = new spc[Fan.keys.FAN_CLAZZ_BODY]();
var n = Fan.fn.last(spc.className.split('.'));
if (Fan.isFunction(sp[n])) { // 找到构造方法
sp = sp[n].apply(sp, arguments) || sp;
// sp[Fan.keys.FAN_CONSTRUCTOR] = sp[n];
delete sp[n];
}
// 给子类所有方法成员加上名称
for (var k in sbo) {
Fan.isFunction(sbo[k]) && (sbo[k][Fan.keys.FAN_FUNCTION_NAME] = k);
}
for (var k in sp) {
if (undefined != k)
// 方法覆盖
if (Fan.isFunction(sp[k])){
// 覆盖子类方法, 当方法成员时,则给方法加上名称
!sp[k][Fan.keys.FAN_FUNCTION_NAME] && (sp[k][Fan.keys.FAN_FUNCTION_NAME] = k);
Fan.oop.isUnimplement(sbo[k]) && (sbo[k] = sp[k]);
} else
// 属性覆盖子类中未声明的属性,即:值为undefined的属性
undefined === sbo[k] && (sbo[k] = sp[k]);
}
// 更改$super指向父类对象
sbo.$super = sp;
// 还原被覆盖的属性
sbo.getClass = sbc[Fan.keys.FAN_CLAZZ_BODY].prototype.getClass;
s = null;
return sbo.$super;
};
// 让$super支持instanceof类型鉴别
c.prototype.$super.prototype = spc === Object ? spc.prototype : spc[Fan.keys.FAN_CLAZZ_BODY].prototype;
cp.toString = (function(n){
return function(){return n;};
})(cp.className);
cp.getInterfaces = (function(a){
return function(){return a || [];};
})(itfs);
// 根据类名,查找并安置在其对应的命名空间下
// 'Fan.util.Class1' --> ['Fan', 'util', 'Class1']
var ns = cn.split('.');
if (ns.length == 1) {
// 'Class1' --> window['Class1'] = c;
window[ns[0]] = cp;
} else {
// 'Fan.util.Class1' --> 'Fan'
var tn = ns[0];
// 'Fan.util.Class1' --> 'Class1'
var name = ns[ns.length - 1];
// 'Fan' --> Fan object
tn = window[tn];
var n = tn;
// Fan --> Fan['util'] --> Fan.util['Class1']
for (var i = 1, l = ns.length; i < l; ++i) {
if (Fan.isPackage(n[ns[i]])) {
n = n[ns[i]];
} else if (!n[ns[i]] && name == ns[i]){
// Fan.util['Class1'] = c
n[name] = cp;
break;
}
}
}
// 继承
Fan.extend(cp, spc);
// 实现接口
Fan.implements(cp, itfs);
// 发布到window域中,以className为句柄名称
window[cn] = cp;
return cp;
}
this.myA=a;
delete this.myA;
}
你都没将a中的属性拷贝到b中
this.myA();其实这里是模拟了call的操作我觉得直接用call会比较直观点
function a(){
this.show=function(){
alert("a");
}
}function b(){
a.call(this)
}function ok(){
var myB= new b();
myB.show();
}
function ClassA(){
this.ClassA = function(arg1,arg2...){
// 提供构造函数
}
}
并满足 new ClassA(123);将会自动调用this.ClassA()并将参数传入,构造完毕后主动删除this.ClassA函数。2、类扩展,即具有继承能力。3、必须支持instanceof关键字进行类型派生鉴定:
(new ClassA() instanceof ClassA) === true4、具有操作关键字,如:super指向父类:
function ClassA(){
this.ClassA = function(arg1,arg2...){
super(arg1); // 构造子类时,可以选择性调用父类构造方法
// ...
} this.method1 = function(arg1,arg2...){
super.method1(arg1); // 存在重写时,可主动调用父类的方法实现
// ...
}
}