1,原型链继承
两个缺点:
1.子类通过其原型prototype对父类实例化,继承了父类。但当父类中的共有属性是引用类型时,会在子类中被所有的实例共用,如此在一个子类实例中更改从父类中继承过来的公有属性时,会影响到其他子类。
2.由于子类是通过原型prototype实例化父类实现继承的,所以在创建父类的时候,无法向父类传递参数,因而在实例化父类的时候无法对父类构造函数内的属性初始化。
function Person(){
this.superType="胡一天";//声明父类
}
Person.prototype.sayName=function(){
alert(this.superType);//为父类添加公有方法
}
function People(name){//声明子类
this.name=name;
this.age=18;
}
People.prototype=new Person();//继承父类 //将父类对象赋值给子类原型,子类原型可访问父类原型上的属性和方法--类式继承原理
//子类添加公有方法
People.prototype.userAge=function(){
alert("年龄是:"+this.age);
}
var user=new People("徐程");
user.sayName();
this.superType="胡一天";//声明父类
}
Person.prototype.sayName=function(){
alert(this.superType);//为父类添加公有方法
}
function People(name){//声明子类
this.name=name;
this.age=18;
}
People.prototype=new Person();//继承父类 //将父类对象赋值给子类原型,子类原型可访问父类原型上的属性和方法--类式继承原理
//子类添加公有方法
People.prototype.userAge=function(){
alert("年龄是:"+this.age);
}
var user=new People("徐程");
user.sayName();
2,借用构造函数继承
call方法可以改变函数的作用环境,在子类中调用这个方法就是将子类中的变量在父类中执行,父类中给this绑定属性,因而子类继承了父类的共有属性。
缺点:
这种类型的继承没有涉及原型prototype,所以父类的原型方法不会被子类继承。如想被子类继承就必须放在构造函数中,这样创造的每个实例都会单独拥有一份而不能共用,违背了代码复用原则
function Person(name,age){//声明父类
this.name=name;//引用类型共有属性
this.age=age;//值类型公有属性
}
//父类声明原型方法
Person.prototype.showBooks=function(){
console.log("我的姓名"+this.name);
}
//声明子类
function SupClass(name,age){
Person.apply(this,arguments);//继承父类
}
var user=new SupClass("orange");
user.showBooks();//TypeError: ins1.showBooks is not a function
this.name=name;//引用类型共有属性
this.age=age;//值类型公有属性
}
//父类声明原型方法
Person.prototype.showBooks=function(){
console.log("我的姓名"+this.name);
}
//声明子类
function SupClass(name,age){
Person.apply(this,arguments);//继承父类
}
var user=new SupClass("orange");
user.showBooks();//TypeError: ins1.showBooks is not a function
3,组合继承(原型+借用构造)
缺点:
父类的构造函数执行了两遍:一次在子类的构造函数中call方法执行一遍,一次在子类原型实例化父类的时候执行一遍。
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.show=function(){
alert("我的姓名"+this.name);
}
function Fale(name,age){
Person.apply(this,arguments);
}
Fale.prototype=new Person();
var user=new Fale("orange");
user.show();
this.name=name;
this.age=age;
}
Person.prototype.show=function(){
alert("我的姓名"+this.name);
}
function Fale(name,age){
Person.apply(this,arguments);
}
Fale.prototype=new Person();
var user=new Fale("orange");
user.show();
4,原型式继承
缺点:
父类对象的引用类型值被共用。
function People(o){
//声明过渡函数对象
function Person(){};
//过渡对象的原型继承父类
Person.prototype=o;
return new Person();
}
var user={
name:"张继科",
friends:["鬼鬼","景甜"]
}
var anotherPer=People(user);
alert(anotherPer.friends);
//声明过渡函数对象
function Person(){};
//过渡对象的原型继承父类
Person.prototype=o;
return new Person();
}
var user={
name:"张继科",
friends:["鬼鬼","景甜"]
}
var anotherPer=People(user);
alert(anotherPer.friends);
5,寄生式继承
function People(o){
//创建一个对象并且添加方法
var clone=Object.create(o);
clone.talk=function(){
alert("你好,"+user.name);
}
return clone;
}
var user={
name:"张继科",
friends:["鬼鬼","景甜"]
}
var anotherPer=People(user);
anotherPer.talk();
//创建一个对象并且添加方法
var clone=Object.create(o);
clone.talk=function(){
alert("你好,"+user.name);
}
return clone;
}
var user={
name:"张继科",
friends:["鬼鬼","景甜"]
}
var anotherPer=People(user);
anotherPer.talk();
6,寄生组合式继承
function SuperType(name) {
this.name=name;
this.colors=['red','blue','green']
}
SuperType.prototype.sayName=function(){
alert(this.name);
}
function SubType(name,job) {
// 继承属性
SuperType.call(this,name);
this.job=job;
}
SubType.prototype=Object.create(SuperType.prototype);
SubType.prototype.constructor=SubType;
var instance=new SubType('恍恍惚惚','student');
instance.sayName();
this.name=name;
this.colors=['red','blue','green']
}
SuperType.prototype.sayName=function(){
alert(this.name);
}
function SubType(name,job) {
// 继承属性
SuperType.call(this,name);
this.job=job;
}
SubType.prototype=Object.create(SuperType.prototype);
SubType.prototype.constructor=SubType;
var instance=new SubType('恍恍惚惚','student');
instance.sayName();