日期:2014-05-16  浏览次数:20342 次

JavaScript中的继承

1.对象冒充

????? 对象冒充指的是在子类中使用子类的this冒充父类的this去执行父类的构造函数,从而获得了父类的属性和方法,但是这种方式只能继承父类构造函数中定义的属性和方法,原型上的任何属性和方法对子类都不可见:

    	//使用对象冒充实现继承
    	function SuperType()
		{
			this.prop = ["prop"];
			
			this.method = function(){return "method";};
		}
		SuperType.prototype.protoProp = "proto";
		
		function SubType()
		{
			//临时方法
			this.inherit = SuperType;
			//冒充继承
			this.inherit();
			//删除临时方法
			delete this.inherit;
		}
		
		var sub = new SubType();
		alert(sub.prop);					//property,继承父类属性
		alert(sub.method());				//method,继承父类方法
		alert(sub.protoProp);				//undefined,不能继承父类原型的属性

?

2.原型链继承

????? 使用原型链可以很方便继承父类的属性和方法,但是若父类的属性是引用类型时可能会存在父类或子类的多个实例的相互影响问题,即某个实例改变了属性,可能对另外的实例可见。

  //原型链继承
		function SuperType()
		{
			this.prop = ["prop"];
			
			this.method = function(){return "method";};
		}
		SuperType.prototype.protoProp = "proto";
		
		function SubType()
		{
		}
		//使用原型链继承
		SubType.prototype = new SuperType();
		
		var sub = new SubType();
		alert(sub.prop);					//property,继承父类属性
		alert(sub.method());				//method,继承父类方法
		alert(sub.protoProp);				//proto,继承父类原型的属性
		
		var sub1 = new SubType();
		var sub2 = new SubType();
		sub1.prop[0] = "another prop";		//改变sub1的属性
		alert(sub2.prop);					//another prop,sub2属性受影响

?

3.借用构造函数

????? 借用构造函数是指在子类的构造函数中调用了父类的构造方法从而继承并初始化父类的属性和方法。但是这种继承方式不能继承父类原型中的属性或者方法,并且方法不能得到复用。

		//借用构造函数实现继承
		function SuperType()
		{
			this.prop = ["property"];
			
			this.method = function(){return "method";};
		}
		SuperType.prototype.protoProp = "proto";
		
		function SubType()
		{
			//调用父类构造函数实现继承
			SuperType.apply(this);		
		}
		
		var sub = new SubType();
		alert(sub.prop);				//property,继承父类属性
		alert(sub.method());			//method,继承父类方法
		alert(sub.protoProp);			//undefined,不能继承父类原型中的属性和方法
		
		var sub1 = new SubType();
		var sub2 = new SubType();
		sub1.prop[0] = "another prop";	//改变sub1的属性
		alert(sub2.prop);				//prop,属性不受sub1影响

?

4.组合继承

????? 组合继承是组合了原型链和借用构造函数的优点,使用原型链继承方法,用借用构造函数继承属性。但是,使用组合继承会两次调用父类的构造方法。第一次是在创建子类的原型对象的时候,这时候会在原型中创建父类的属性和方法;第二次是当需要创建子类实例的时候,在子类构造函数内部调用,这时会创建父类的属性和方法,去屏蔽原型上相应的属性和方法。

		//使用组合继承实现继承
		function SuperType()
		{
			//属性保存在构造函数内
			this.prop = ["property"];
		}
		//方法保存在原型上
		SuperType.prototype.method = function(){return "method";};
		
		function SubType()
		{
			//调用父类构造函数继承属性
			SuperType.apply(this);
		}
		//使用原型继承父类方法
		SubType.prototype = new SuperType();
		
		var sub = new SubType();
		alert(sub.prop);				//property,继承父类属性
		alert(sub.method());			//method,继承父类方法
	
		var sub1 = new SubType();
		var sub2 = new SubType();
		sub1.prop[0] = "another prop";	//改变sub1的属性
		alert(sub2.prop);				//prop,属性不受sub1影响

?

?5.寄生组合式继承

????? 使用寄生组合式会复制父类的原型赋给子类的原型,从而避免在子类的原型上创建不必要的、多余的属性。

		//使用寄生组合式继承
		//用于复制父类的原型的函数
		function copyPrototype(proto)
		{
			function Temp(){};
			Temp.prototype = proto;
			return new Temp();
		}
		
		function SuperType()
		{
			//属性保存在构造函数内
			this.prop = ["property"];
		}
		//方法保存在原型上
		SuperType.prototype.method = function(){return "method";};
		
		function SubType()
		{
			SuperType.apply(this);
		}
		
		//构造原型链
		var subProto = copyPrototype(SuperType.prototype);
		subProto.constructor = SubType;
		SubType.prototype = subProto;
		
		var sub = new SubType();
		alert(sub.prop);				//property,继承父类属性
		alert(sub.method());			//method,继承父类方法

?

?