js中的继承

继承,一个子类,一个超类,子类想获取超类中的属性和方法,获取之后不满意也可以重写超类中的方法。

新建一个超类:

function fa(){
			this.name='father';
		}
		fa.prototype.getname=function(){
			return this.name;
		};

在建一个子类:

function ch(){
			this.age=10;
		}
ch.prototype.getage=function(){
			return this.age;
		};
怎样让子类获得超类中的属性和方法呢?那就用new实例化一个超类的实例,并把这个实例赋值给子类的原型prototype即可:

ch.prototype=new fa();  //实现了继承
这时,子类就不仅拥有自身的属性和方法,还拥有超类的属性和方法,可以实例化一个子类的实例验证一下:

var o=new ch();  //实例化子类
alert(o.getname());//father 调用原本超类中的方法,且能正确运行
alert(o.getage());//10 自己本身的方法
以上就是基本的继承方式,无论超类中的属性、方法是定义在函数中的还是在原型中的子类都能继承。下面演示一下继承后再重写:

function fa(){
			this.name='father';
		}
		fa.prototype.getname=function(){
			return this.name;
		};

		function ch(){
			this.age=10;
		}
		ch.prototype=new fa();
		
		ch.prototype.getage=function(){
			return this.age;
		};
		ch.prototype.getname=function(){ //此处重写了超类中的getname
			return 'newname';
		};
		
		var o=new ch();
		alert(o.getname());//newname   此时执行的是重写后的新getname所以返回newname
		alert(o.getage());

这种继承方式也存在一个问题,那就是对于引用型数据的原型会被实例共享,下面演示一个非引用型和一个引用型:

非引用型实例不共享:

	
		function fa(){
			this.name='father';
		}
		fa.prototype.getname=function(){
			return this.name;
		};
	
		function ch(){
			this.age=10;
		}
		ch.prototype=new fa();
		
		ch.prototype.getage=function(){
			return this.age;
		};
		var o=new ch();//两者相互独立
		var o2=new ch();//两者相互独立
		alert(o.getname());
		alert(o2.getname());
		o.name='newname';//更改o的name
		alert(o.name);//o改变
		alert(o2.name);//但o2不变,相互不受影响

引用型数据实例会共享:

function fa(){
			this.color=['red','green','blue']; //这是个引用型数据
		}
		function ch(){}
		ch.prototype=new fa();
		var o1=new fa();
		var o2=new fa();
		alert(o1.color);
		alert(o2.color);
		o1.color.push('newcolor');//更改o1的属性color
		alert(o1.color);//red,green,blue,newcolor  o1改变
		alert(o2.color);//red,green,blue,newcolor  o2也跟着改变,因为color是引用型,两者都指向同一个引用型数据color

借用构造函数可解决上述引用型数据的问题:

  function sup(){
			this.color=['red','green','blue'];
		}

		function sub(){
			//继承了sup
			sup.call(this);//关键代码:在子类的构造函数中调用超类的构造函数,从而实现继承
		}
		var o1=new sub();
		var o2=new sub();
		alert(o1.color);//'red','green','blue'
		alert(o2.color);//'red','green','blue'
		o1.color.push('new');//用o1更改color
		alert(o1.color);//改变'red','green','blue',‘new’
		alert(o2.color);//此时不会改变,依然是'red','green','blue'
关键代码在注释中已经说明,但借用构造函数的方式依然有个通病:不能函数复用,也就是该共享的不能共享,所以结合两者,通过组合继承的方式更加常用:

function sup(name){
			this.name=name;
			this.color=['red','green','blue'];
		}
		sup.prototype.sayname=function(){
			alert(this.name);
		};
		function sub(name,age){
			//构造函数继承属性(防止实例共享引用型属性)
			sup.call(this,name);
			this.age=age;
		}
		//原型继承方法,实现方法的共享,实现代码复用
		sub.prototype=new sup();
		sub.prototype.sayage=function(){
			alert(this.age);
		};
		var o=new sub('tom',10);
		var o2=new sub('cat',20);
		alert(o.name);
		alert(o.color);
		o.sayname();
		o.color.push('iii');//修改color属性
		alert(o.color);//改变
		alert(o2.color);//不变
通过上述的代码可看出规律,不需共享的属性借用构造函数实现继承。把需要共享的方法用原型prototype来实现继承。






原文地址:https://www.cnblogs.com/chayangge/p/4288697.html