I have posted this post couple of days ago where I was looking for a good approach for making Extending Class like behaviour for JS objects.
With the help of all discussants,I was able to make the extend functionality to work. But since I can only extend a single class, I was wondering if multiple class/object extending is possible in JS.
I have tried to simulate this behaviour in below code, but unfortunately it doesn't really work as I would expect. The last object always overwrites the base class ( it's just a simple object where I'm storing all the objects that are used to extend )
As you can see below the :
[Rabbit] extends [WorldObject] , [Animal]
[BigRabbit] extends [Rabbit]
But for some reason , the WorldObject properties are always overwritten by Animal. I also know that this is the part
for(var c=0; c <= (NewClass.Extend.length - 1); c++){
if(typeof NewClass.Extend[c] === 'function'){
MultiExtClass.prototype = Object.create(NewClass.Extend[c].prototype);
}
}
which is causing that the MultiExtClass is being overwritten, instead of extending.
"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)