js实现继承
一、原型继承
function Father(lastname,sex){ this.lastname=lastname; //姓 this.sex=sex;//性别 } //父类原型属性 Father.prototype.xo='xxx'; //子类 function Son(firstname){ this.firstname=firstname;//名 } Son.prototype=new Father('杨'); //原型继承,son的原型已经指向了father对象的实例 var son = new Son('清'); alert(son.firstname);//清 alert(son.lastname);//杨 继承的属性 alert(son.xo);//xxx 继承的原型属性 alert(son.sex);//undefined//继承时未传值
缺点:继承后还必须给父类传参, new Father('杨'), 不能把参数直接传入子类中
二、借用构造函数继承
//父类 function Father(lastname,sex){ this.lastname=lastname; //姓 this.sex=sex;//性别 } //父类原型属性 Father.prototype.xo='xxx'; //子类 function Son(lastname,firstname){ Father.call(this,lastname);//将Father构造函数绑定到Son this.firstname=firstname;//名 } var son = new Son('杨','清'); alert(son.firstname);//清 alert(son.lastname);//杨 继承的属性 alert(son.xo);//undefined 未能继承到原型属性 alert(son.sex);//undefined//不需要继承属性
缺点:未能继承到原型属性
三、 组合继承(原型继承+借用构造函数继承)
function Father(lastname,sex){ this.lastname=lastname; //姓 this.sex=sex;//性别 } //父类原型属性 Father.prototype.xo='xxx'; //子类 function Son(lastname,firstname){ Father.call(this,lastname);//借用构造函数继承 this.firstname=firstname;//名 } Son.prototype=new Father(); //原型继承,不用传参 只为继承原型属性 var son = new Son('杨','清'); alert(son.firstname);//清 alert(son.lastname);//杨 继承的属性 alert(son.xo);//xxx 继承到原型属性 alert(son.sex);//undefined//不需要继承属性
缺点:虽然原型继承时new Father()没有传入参数,还是又继承了一次Father的模板
四、 组合继承(最终版)
var __extends = this.__extends || function (sub, sup) { for (var p in sup) if (sup.hasOwnProperty(p)) sub[p] = sup[p];//继承父类自身属性 function __() { this.constructor = sub; } //创建一个空函数 并将构造指向子类 __.prototype = sup.prototype;//空函数原型指向父类原型 //以上代码 创建出了一个空函数 1.无属性模板。2.构造函数是子类。3.原型是指向父类原型 sub.prototype = new __();//改变原型对象, 指向空函数 sub.superClass =sup.prototype;//保持父类原型 if(sup.prototype.constructor==Object.prototype.constructor){ //如果简单原型覆盖 则手动添加 sup.prototype.constructor=sup; } }; function Person(name,age){ this.name=name; this.age=age; } Person.ff='sssc'; Person.prototype={ sayName : function(){ alert(this.name); } } function Boy(name ,age,sex){ Boy.superClass.constructor.call(this,name,age); Person.call(this,name,age); this.sex=sex; } __extends(Boy,Person);//继承 var b=new Boy('对对',23,'男'); alert(b.name); alert(b.age); alert(b.sex); b.sayName(); alert(Boy.prototype.constructor.ff);//输出父类自身属性