1、组合继承
组合继承带来的问题很明细就是父类的构造函数会调用两次,如:
function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.color=["red","blue","green"]; } Person.prototype.sayHello=function(){ console.log("hello word!")}; function Man(name,age,sex,job){ Person.call(this,name,age,sex);// 第二次 this.job=job; } Man.prototype=new Person();//第一次 var instance=new Man("张三",20,"男","农民");
instance.color.push("black"); console.log(instance.color);//["red", "blue", "green", "black"] console.log(instance.job);//农民 console.log(instance.sayHello);//hello word! var instance2=new Man("张三",20,"男","地主"); console.log(instance2.color); //["red", "blue", "green"] console.log(instance2.job);//地主 console.log(instance2.sayHello);//hello word!
2、寄生组合式继承
js中继承的本质是对象的内部属性_proto_ 指向原型对象,那么解决组合继承的问题其实很简单,我们只要克隆一个父类的原型对象来代替这句代码
Man.prototype=new Person();
那理论是不是也是可以的呢?
继续看代码:
//寄生组合式继承 function inheritPrototype(child,parent){ var prototype=Object(parent.prototype);// 第一步:创建一个变量接收父类原型对象 prototype.constructor=child;// 第二步:原型对象构造指向子类 child.prototype=prototype;// 第三步:用父类副本的原型对象重写子类原型对象 } //基类 function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.color=["red","blue","green"]; }
Person.prototype.sayHello=function(){ console.log("hello word!")}; //子类 function Man(name,age,sex,job){ Person.call(this,name,age,sex);//继承属性 this.job=job; } inheritPrototype(Man,Person);// 继承原型方法 var instance=new Man("张三",20,"男","农民"); instance.color.push("black");// 数组添加一个元素 console.log(instance.color);//["red", "blue", "green", "black"] console.log(instance.job);//农民 console.log(instance.sayHello);//hello word! var instance2=new Man("张三",20,"男","地主"); console.log(instance2.color); //["red", "blue", "green"] console.log(instance2.job);//地主 console.log(instance2.sayHello);//hello word!
事实证明这样处理是可以的。寄生组合式继承只调用一次Person 构造函数,与此同时还原型链还能保持不变;普遍认为这是最理想的继承模式了;