JavaScripy关于对继承原型链,借用构造函数和组合继承的理解

    ECMAScript将原型链作为实现继承的主要方法。基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。原型链和借用构造函数都可以实现继承,只是缺点都比较明显,然后就引出一个组合继承的方法。本文记录了我对这三个继承方法的理解。


1.//原型链继承  
function Supertype(){     //构造函数1
this.property=true;

}
Supertype.prototype.getSuperValue=function(){        //原型1添加了一个方法

return this.property;
}
function Subtype(){            //构造函数2
this.subproperty=false;
}


Subtype.prototype=new Supertype();  //函数2继承函数1  通过prototype使得supertype成为subtype的原型属性,继承了函数1 的所有属性和方法
Subtype.prototype.getSubValue=function(){  //函数2 定义了一个方法

return this.subproperty;
}

var instance=new Subtype();   //创建一个函数2 的实例
alert(instance.getSuperValue());  //true

原型链的缺点:包含引用类形的的原型属性会被所有实例共享,在通过原型来实现继承时,原型实际上会变成另一个类型的实例。于是原先的实例属性也就顺理成章地变成了现在的原型属性了。

2.//借用构造函数:在子类型构造函数的内部调用超类型构造函数
function Supertype(){   //超类
this.colors=["red","blue","green"];
}
function Subtype(){    //子类,在构造函数中调用超类
Supertype.call(this);

}
var instance1=new Subtype();  //实例化1
instance1.colors.push("black");  
alert(instance1.colors);  //red,blue,green,black


var instance2=new Subtype();  //实例化2
alert(instance2.colors);  //red,blue,green,
    在实例化1的时候,调用subtype构造函数,subtype又调用supertype,可以看作是直接对supertype进行实例化,因此,引用类型属性colors是在构造函数中而不是像原型链被继承到原型属性中,也就不会因为实例化1改变了引用类型而导致实例化2也改变,弥补了原型链的缺点。
    借用构造函数的缺点:仅仅借用构造函数,方法都在构造函数中定义,因此函数复用也就无从谈起。而且在超类型原型中定义的方法对子类型不可见,因为子类型只是继承了超类构造方法的属性,没有继承超类原型的方法。

3 组合继承 

    鉴于上面两个方法的缺点明显,结合两者优点,扬长避短,组合继承应运而生

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;

}

Subtype.prototype=new Supertype();   // 原型链继承方法
Subtype.prototype.constructor=Subtype;
Subtype.prototype.sayage=function(){

alert(this.age);
};
var instance1=new Subtype("Nice",23);
instance1.colors.push("black");
alert(instance1.colors);  //red,blue,green,black
instance1.sayname(); //Nice
instance1.sayage();  //23


var instance2=new Subtype("Greg",26);
alert(instance2.colors);//red,blue,green,
instance2.sayname();  //Greg
instance2.sayage();   //26

组合继承使用了借用构造函数,但是可以调用超类原型的方法了。使用了原型链继承,但是不会出现引用类型值问题


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
原型链继承(Prototype Inheritance)在JavaScript中是通过创建一个新对象并让它引用另一个对象的原型来实现的。例如: ```javascript function Parent() {} Parent.prototype.method = function() { console.log('Parent method'); }; let child = new Parent(); child.method(); // 输出: "Parent method" ``` **借用构造函数继承**(Constructo r Chaining)利用已有构造函数作为父类,通过`new`关键字传递给子类实例化过程,间接实现了继承: ```javascript function Parent() { this.parentProp = 'parent'; } function Child() { Parent.call(this); // 借用父类构造函数 this.childProp = 'child'; } Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; let childInstance = new Child(); console.log(childInstance.parentProp); // 输出: "parent" console.log(childInstance.childProp); // 输出: "child" ``` **组合继承**(Mix-in or Prototype Mixing)结合原型链构造函数继承,允许从多个源继承属性和方法: ```javascript function Mixin(target) { for (let prop in Mixin.prototype) { target[prop] = Mixin.prototype[prop]; } } function Parent() { this.parentProp = 'parent'; } Mixin(Parent.prototype); let child = new Parent(); console.log(child.parentProp); // 输出: "parent" ``` **ES6的class类继承**(Class-based Inheritance)使用`extends`关键字实现: ```javascript class Parent { constructor() { this.parentProp = 'parent'; } parentMethod() { console.log('Parent method'); } } class Child extends Parent { constructor() { super(); this.childProp = 'child'; } childMethod() { console.log('Child method'); } } let childInstance = new Child(); childInstance.parentMethod(); // 输出: "Parent method" childInstance.childMethod(); // 输出: "Child method" ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值