Skip to content

Commit

Permalink
修复多重继承调用super出现死循环的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
welefen committed Sep 17, 2014
1 parent b4edf76 commit e622ef9
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 15 deletions.
48 changes: 34 additions & 14 deletions lib/Common/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,30 +72,50 @@ global.Class = function (prop, superCls) {
//如果当前类没有这个方法,则直接返回。
//用于在a方法调用父级的b方法
if (!this[name]) {
this.super_c = null;
return;
}
var super_ = this.super_c ? this.super_c.super_ : this.constructor.super_;
if (!super_) {
this.super_c = null;
return;
}
var super_ = this.constructor.super_;
//如果父级没有这个方法,那么直接返回
if (!isFunction(super_.prototype[name])) {
this.super_c = null;
return;
}
while(this[name] === super_.prototype[name] && super_.super_){
super_ = super_.super_;
}
this.super_c = super_;
if (!this.super_t) {
this.super_t = 1;
}
//如果参数不是数组,自动转为数组
if (arguments.length === 1) {
data = [];
}else if (!isArray(data)) {
data = [data];
if (!isArray(data)) {
data = arguments.length === 1 ? [] : [data];
}
while(1){
if (this[name] === super_.prototype[name] && super_.super_) {
super_ = super_.super_;
}else{
var t = ++this.super_t;
var method = super_.prototype[name];
var ret;
switch(data.length){
case 0:
ret = method.call(this);
break;
}
case 1:
ret = method.call(this, data[0]);
break;
case 2:
ret = method.call(this, data[0], data[1]);
break;
default:
ret = method.apply(this, data);
}
if (t === this.super_t) {
this.super_c = null;
this.super_t = 0;
}
var method = super_.prototype[name];
delete super_.prototype[name];
var ret = method.apply(this, data);
super_.prototype[name] = method;
return ret;
};
if (prop) {
Expand Down
93 changes: 92 additions & 1 deletion test/Common/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,26 +149,103 @@ describe('Class', function(){

//深度继承并调用super
var C1 = Class({
name: 'C1',
init: function(){
return 'C1';
},
getName: function(){
return this.name;
},
getName1: function(){
return this.super('getName');
}
})
var C2 = Class({
name: 'C2',
init: function(){
var c = this.super('init');
return c + 'C2';
},
getName: function(){
return this.super('getName') + this.name;
},
getName3: function(){
return this.super('getName', [1, 2, 3, 4])
}
}, C1);
var C3 = Class({
name: 'C3',
init: function(){
var c = this.super('init');
return c + 'C3';
},
getName: function(){
return this.super('getName') + this.name;
}
}, C2);
it('deep inherits', function(){
var C4 = Class({
name: 'C4',
init: function(){
var c = this.super('init');
return c + 'C4';
},
getName: function(){
return this.super('getName') + this.name;
}
}, C3);
var C5 = Class({
init: function(){
var c = this.super('init');
return c + 'C5';
},
getName: function(){
return this.name;
},
getName1: function(){
return 'getName1';
},
getName2: function(){
return this.super('getName1');
}
}, C4);
it('deep inherits 3', function(){
var instance = C3();
assert.equal(instance.__initReturn, 'C1C2C3');
})
it('deep inherits 4', function(){
var instance = C4();
assert.equal(instance.__initReturn, 'C1C2C3C4');
})
it('deep inherits 4 twice', function(){
var instance = C4();
assert.equal(instance.__initReturn, 'C1C2C3C4');
var instance = C4();
assert.equal(instance.__initReturn, 'C1C2C3C4');
})
it('deep inherits 5', function(){
var instance = C5();
assert.equal(instance.__initReturn, 'C1C2C3C4C5');
})
it('c4.getName', function(){
var instance = C4();
var name = instance.getName();
assert.equal(name, 'C4C4C4C4');
})
it('c5.getName', function(){
var instance = C5();
var name = instance.getName();
assert.equal(name, 'C4');
})
it('c1.getName1', function(){
var instance = C1();
var name = instance.getName1();
assert.equal(name, undefined)
})
it('c2.getName3', function(){
var instance = C2();
var name = instance.getName3();
assert.equal(name, 'C2')
})
})

/**
Expand Down Expand Up @@ -250,6 +327,12 @@ describe('extend', function(){
var a = extend({}, {name: undefined, value: undefined});
assert.deepEqual(a, {});
})

it('extend', function(){
var F = Class();
F.extend();
assert.deepEqual(F.__prop, {})
})
})

/**
Expand Down Expand Up @@ -642,6 +725,14 @@ describe('isPromise', function(){
assert.equal(isPromise(getPromise('', true)), true)
})
})

describe('rand', function(){
it('rand(0, 10)', function(){
var r = rand(0, 10);
var f = (r >= 0 && r <= 10);
assert.equal(f, true);
})
})
/**
* 生成一个Promise
* @return {[type]} [description]
Expand Down

0 comments on commit e622ef9

Please sign in to comment.