js中的继承

来源:互联网 发布:十月革命100周年 知乎 编辑:程序博客网 时间:2024/06/05 04:18

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

新建一个超类:

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(){ //此处重写了超类中的getnamereturn 'newname';};var o=new ch();alert(o.getname());//newname   此时执行的是重写后的新getname所以返回newnamealert(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的namealert(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的属性coloralert(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(){//继承了supsup.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更改coloralert(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来实现继承。






0 0
原创粉丝点击