js原型继承的几种方式(简单理解)

js原型继承的几种方式

  1. 原型链继承
  2. 构造函数继承(对象冒充继承)
  3. 组合继承(原型链继承+构造函数继承)
  4. 原型式继承
  5. 寄生组合式继承

1.原型链继承

什么是原型链???
这里是我找到的几个比较清楚的图片
在这里插入图片描述

在这里插入图片描述
众所周知,每个构造函数都有一个原型对象,原型对象都包括一个指向构造函数的指针,而实例都包括一个指向原型对象的内部指针,如果我们将原型对象等于另一个构造函数的实例,此时的原型对象将包含一个指向另一个原型的指针,层层递进就形成了原型链。

function superf() {
    this.name = "xuxiaotong";
}

function subf() {
    this.age = "21"; 
}
subf.prototype = new superf();//subf继承了superf,通过原型,形成链条
var test = new subf();
console.log(test.name) //xuxiaotong

有两个问题:引用共享和超类无法传参。

2.构造函数继承(对象冒充继承)

function superf(name) {
    this.name = name
}
superf.prototype.getname = function(){
    return this.name 
}

function subf(name,age) {
    superf.call(this,name)
    this.age = age; 
}


var test = new subf("xuxiaotong",21);
console.log(test.name) //xuxiaotong
console.log(test.age) //21

借用构造函数虽然解决了刚才两种问题, 但没有原型, 复用则无从谈起。 所以, 我们需要原型链+借用构造函数的模式,这种模式成为组合继承。

3.组合继承(原型链继承+构造函数继承)

//原型链加构造函数继承
function spuerf(name){
    this.name = name
}
spuerf.prototype.getname = function(){
    return this.name
}

function subf(name,age,hobby){
    spuerf.call(this,name)
    this.age = age
    this.hobby =hobby
}

subf.prototype = new spuerf()

subf.prototype.getintro = function(){
    return "我叫:" + this.name +"\n" +this.age + "岁" +"\n"+ "爱好是:" +this.hobby
}
var test =  new subf("xutong",21,"敲代码")
console.log(test.getintro())

在这里插入图片描述
虽然可以解决上面的个问题,但是这种方法在执行的过程中会两次调用超类构造函数(耗内存)。

4.原型式继承

function obj(o) { 
    function F() { } 
    F.prototype = o; 
    return new F(); 
}
var test  = {
    name:"xuxiaotong",
    age:21,
    getintro:function(){
        return this.name + "已经" + this.age + "了"
    }

}
 var test1 = obj(test)

 console.log(test1.name)  //xuxiaotong
 console.log(test1.age)  //21
 test.age = 22
 console.log(test.age)  //22
 console.log(test1.getintro())  //xuxiaotong已经22了

上例子中,在obj()函数内部,先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回一个临时类型的实例。

该继承需要有一个对象可以作为另一个对象的基础,在根据具体需求加以修改。

5.寄生式继承

var createAnother = function(sub){
    var clone = Object(sub)
    clone.getintro = function(){
        return this.name + this.age
    }
    return clone
}

var test  = {
    name:"xuxiaotong",
    age:21,
    

}
 var test1 = createAnother(test)

 console.log(test1.getintro())  //xuxiaotong已经22了


方法在函数中定义,无法得到复用。

6.寄生组合式继承

寄生组合式继承解决了组合式继承两次调用的问题。

组合式继承两次调用:
在这里插入图片描述
下面是寄生组合式继承

function inheritPrototype(subType, superType){
    var prototype = object(superType.prototype); //创建对象
    prototype.constructor = subType; //增强对象
    subType.prototype = prototype; //指定对象
}
function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
    alert(this.name);
};
function SubType(name, age){
    SuperType.call(this, name);
    this.age = age;
}
inheritPrototype(SubType, SuperType);//实现继承
SubType.prototype.sayAge = function(){
    alert(this.age);

};
  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值