2

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)

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.