JS对象继承方法

JS对象继承方法


原型链

通过原型链来实现继承,给原型添加的代码一定要放在替换原型的语句之后的,而且不能使用原型对象字面量创建原型方法。
如果超类型中包含有引用类型,成为了子类型的共享属性,并且不能向超类型的构造函数传参。故实践中很少用!

function Person(major){    
    this.major=major;
}
Person.prototype.showMajor=function(){
    alert(this.major);
}
function Student(id,name){
    this.id=id;
    this.name=name;
}
Student.prototype=new Person('English');
Student.prototype.showId=function(){
    alert(this.id);
}
var xiaoming=new Student('001','xiaoming');//xiaoming.major='English'
//xiaoming.constructor=Person

借用构造函数

在子类型构造函数的内部调用超类型的构造函数,利用applycall函数
实现了向超类型构造函数传参,但是在超类型的原型中定义的方法对于子类型不可见,只能在构造函数中定义,就成构造函数模型。
构造函数模型中的缺点,很少单独使用。

function Person(major){   
    this.major=major;
}

function Student(id,name,major){
    Person.call(this,major)
    this.id=id;
    this.name=name;
}
var xiaoming=new Student('001','xiaoming','English');

组合继承

伪经典继承,使用原型链实现对原型属性和方法的继承,而通过借用构造函数实现对实例属性的继承
调用两次超类型的构造函数,子类型实例中会包含超类型的全部实例属性,而必须得重写这些属性。
最常用的继承模式

function Person(major){   
    this.major=major;
}
Person.prototype.showMajor=function(){
    alert(this.major);
}
function Student(id,name,major){
    Person.call(this.major);//第二次调用超类型的构造函数
    this.id=id;
    this.name=name;
}
Student.prototype=new Person();//第一次调用超类型的构造函数
Student.prototype.contructor=Student;
Student.prototype.showId=function(){
    alert(this.id);
}
var xiaoming=new Student('001','xiaoming','English');//xiaoming.major='English',有一个major但是却是undefined

原型式继承

借助已有的对象创建新对象,不需要构造函数。利用下面的函数进行实现:

function object(o){
     function F(){}
     F.prototype=o;
     return new F();
}

或者用Object.creat()*1实现

Object.creat()* 2个参数,1个可选;对象,对象;用作原型的对象,为新对象添加额外属性的对象 以传入对象为原型创建新的对象,第二参数的格式为详细的通过描述符来定义属性
在只想让一个对象和另外一个对象保持类似的情况用这种方式,包含引用类型的属性始终都会共享。和原型模式一样

function object(o){
     function F(){}
     F.prototype=o;
     return new F();
}
var person={
     name:'zhangsan',
     id:'000',
     major:undefined
};
var xiaoming=object(person);
xiaoming.name='xiaoming';
xiaoming.id='001';
xiaoming.major='English';
var xiaohong=Object.create(person,{
     name:{
          value:'xiaohong',
          enumerable:true
     },
     id:{
          value:'002',
          enumerable:true
     },
     major:{
          value:'Math',
          enumerable:true
     }
});

寄生式继承

创建一个仅用于封装继承过程的函数,在函数内部以某种方式来增强对象。
与原型式继承思想相同,但是把增强对象的代码都封装到一个函数中,因此不仅仅是像原型式继承一样复制,而且还进行增强。可以不用object(),只要是返回对象的均可。
与构造函数模式类似,做不到函数复用。
在主要考虑对象而不是自定义类型和构造函数的情况下,也一种有用的模式,

function object(o){
     function F(){}
     F.prototype=o;
     return new F();
}
function createObject(o){
     var oo = object(o);
     oo.showName=function(){
          alert(this.name);
     };
     return oo;
}
var person={
     name:'zhangsan',
     id:'000',
     major:undefined
};
var xiaoming=object(person);
xiaoming.showName=function(){
     alert(this.name);
};
var xiaohong=createObject(person);

寄生组合继承

使用借用构造函数实现继承属性,用原型链的混成形式来继承方法,即用寄生式继承来借助超类型来创建子类型原型
解决了两次调用超类型构造函数的问题,没有多余的属性,原型链保持不变,最理想的继承方式

function object(o){
     function F(){}
     F.prototype=o;
     return new F();
}
function Person(major){   
    this.major=major;
}
Person.prototype.showMajor=function(){
    alert(this.major);
}
function Student(id,name,major){
    Person.call(this.major);//第二次调用超类型的构造函数
    this.id=id;
    this.name=name;
}
Student.prototype=object(Person.prototype);//第一次调用超类型的构造函数
Student.prototype.contructor=Student;
//inheritPrototype(Person,Student);
Student.prototype.showId=function(){
    alert(this.id);
}
var xiaoming=new Student('001','xiaoming','English');//xiaoming.major='English',没有多余的属性了

可以像寄生式继承一样写成一个函数:

function inheritPrototype(father,child){
    var clone=object(father.prototype);
    clone.contructor=child;
    child.prototype=clone;
}

  1. *号表示ECMAScript5新增的方法,需要较新版本的浏览器支持
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值