我几天前发布了这个post,我正在寻找一种很好的方法来为JS对象进行扩展类行为。
在所有讨论者的帮助下,我能够使扩展功能发挥作用。但是因为我只能扩展一个类,所以我想知道在JS中是否可以进行多个类/对象扩展。
我试图在下面的代码中模拟这种行为,但不幸的是它并没有像我期望的那样真正起作用。最后一个对象总是覆盖基类(它只是一个简单的对象,我存储了所有用于扩展的对象)
如下所示:
[Rabbit] extends [WorldObject] , [Animal]
[BigRabbit] extends [Rabbit]
但由于某些原因,WorldObject
属性始终被Animal
覆盖。我也知道这是部分
for(var c=0; c <= (NewClass.Extend.length - 1); c++){
if(typeof NewClass.Extend[c] === 'function'){
MultiExtClass.prototype = Object.create(NewClass.Extend[c].prototype);
}
}
导致MultiExtClass
被覆盖,而不是扩展。
"use strict"
var CopyObjProps =(function(target, source){
var getObjKeys = Object.keys || function(o) {
var keysArray = [];
for(var name in o) {
if (o.hasOwnProperty(name))
keysArray.push(name);
}
return keysArray;
};
var ObjectPropsNames = getObjKeys;
ObjectPropsNames(source).filter(function(el) {
return ['Extend', 'Initialize'].indexOf(el) == -1
}).forEach(function(el) {
target.prototype[el] = source[el];
});
return target;
});
var Extendable = (function(){
this.extend = function(NewClass){
var ExtClass = function() {
if(typeof NewClass.Extend === 'function'){
NewClass.Extend.apply(this, arguments);
}
if(NewClass.Initialize){
NewClass.Initialize.apply(this, arguments);
}
};
if(typeof NewClass.Extend === 'function'){
ExtClass.prototype = Object.create(NewClass.Extend.prototype);
}
CopyObjProps(ExtClass, NewClass);
return ExtClass;
}
});
var MultiExtendable = (function(){
this.extend = function(NewClass){
var MultiExtClass = function(args){
for(var c=0; c <= (NewClass.Extend.length - 1); c++){
if(typeof NewClass.Extend[c] === 'function'){
NewClass.Extend[c].call(this, args);
}
}
if(NewClass.Initialize){
NewClass.Initialize.call(this, args);
}
};
for(var c=0; c <= (NewClass.Extend.length - 1); c++){
if(typeof NewClass.Extend[c] === 'function'){
MultiExtClass.prototype = Object.create(NewClass.Extend[c].prototype);
}
}
CopyObjProps(MultiExtClass, NewClass);
return MultiExtClass;
}
});
var Class = (function(NewClass){
if(arguments.length != 0){
var self = Object.getPrototypeOf(this);
if(typeof NewClass.Extend === "function"){
Extendable.call(self);
return self.extend(NewClass);;
}
else if(typeof NewClass.Extend === "object"){
MultiExtendable.call(self);
return self.extend(NewClass);
}
else{
var NotExtClass = function() {
if(typeof NewClass.Initialize === "function"){
NewClass.Initialize.apply(NewClass, arguments);
}
};
CopyObjProps(NotExtClass, NewClass);
return NotExtClass;
}
}
});
var WorldObject = new Class({
Initialize: function(args){
console.log("WorldObject-initialized");
},
Haha: function(){},
test: 4
});
var Animal =new Class({
Initialize: function(args){
console.log("Animal-initialized");
this.setName(args.name)
},
setName: function(name){
this.name = name || null;
console.log("Animal-changed name :", this.name)
},
animal: 14
});
var Rabbit = new Class({
Extend: [ WorldObject, Animal],
Initialize: function(args){
console.log("Rabbit-initialized ");
},
changeName: function(a){
this.name = a;
console.log("Rabbit-changed name :", this.name)
},
rabbit: 1
});
var BigRabbit = new Class({
Extend: Rabbit,
Initialize: function(args){
console.log("BigRabbit-initialized ")
this.changeName(args.name);
},
changeName: function(a){
this.name = a;
console.log("BigRabbit-changed name :", this.name)
},
alex: 7
});
var NewRabbit = new BigRabbit({name: "JustArabbit"});
NewRabbit.changeName("RabbitTest");
console.log(NewRabbit instanceof BigRabbit)
console.log(NewRabbit instanceof Animal)
console.log(NewRabbit instanceof Rabbit)
console.log(NewRabbit instanceof WorldObject)
console.log(NewRabbit)
&#13;