在javascript中扩展多个对象/ classess

时间:2015-09-25 22:24:51

标签: javascript oop

我几天前发布了这个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被覆盖,而不是扩展。

&#13;
&#13;
"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;
&#13;
&#13;

0 个答案:

没有答案