继承

继承是面向对象中一个比较核心的概念。其他正统面向对象语言都会用两种方式实现继承:一个是接口实现,一个是继承。而ECMAscript 只支持继承,不支持接口实现,而实现继承方式依靠原型链完成。

1、原型链继承

function Box(){
    this.name = 'Lee';
}

function Desk(){ 
    this.age = 100;
}

Desk.prototype = new Box();              //Desk 继承了Box,通过原型,形成链条
var desk = new Desk();
alert(desk.age);

ps:在JavaScript 里,被继承的函数称为超类型(父类,基类也行,其他语言叫法),继承的函数称为子类型(子类,派生类)。原型链继承有两个缺点:1、引用类型的原型问题。2、子类型无法给超类型传参。

2、借用构造函数技术(对象冒充)

function Box(name,age){
    this.name = name;
    this.age = age;
}

function Desk(name,age){
    Box.call(this,name,age);                          //对象冒充,对象冒充只能继承构造里的信息。原型里的信息无法继承。
}

var desk = new Desk('Howie',200);
alert(desk.name);

3、组合继承(原型链+对象冒充)

function Box(name,age){
    this.name = name;
    this.age = age;
}
Box.prototype.run = function(){
    return this.name + this.age +'运行中...';
}

function Desk(name,age){
    Box.call(this,name,age);            //对象冒充,第一次Box调用
}

Desk.prototype = new Box();             //原型链继承,第二次Box调用
var Desk = new Desk('Howie','100'); alert(Desk.run());

 组合式继承是JavaScript 最常用的继承模式;但,组合式继承也有一点小问题,就是超类型在使用过程中会被调用两次:一次是创建子类型的时候,另一次是在子类型构造函数的内部。

4、寄生组合继承

//临时中专函数
function obj(o) {                //o表示将要传递进入的一个对象 
    function F() {}                //F构造是一个临时新建的对象,用来存储传递过来的对象
    F.prototype = o;            //将o对象实例赋值给F构造的原型对象
    return new F();                //最后返回这个得到传递过来对象的对象实例
}

//寄生函数
function create(box, desk) {
    var f = obj(box.prototype);            //此时f.constructor 指向box
      f.constructor = desk;                //调整原型构造指针,让f.constructor 指向desk
    desk.prototype = f;        
}

function Box(name, age) {
    this.name = name;
    this.age = age;
}

Box.prototype.run = function () {
    return this.name + this.age + '运行中...'
}

function Desk(name, age) {
    Box.call(this, name, age);                //对象冒充
}

//通过寄生组合继承来实现继承
create(Box, Desk);                            //这句话用来替代Desk.prototype = new Box();


var desk = new Desk('Lee',100);
alert(desk.run());

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

原文地址:https://www.cnblogs.com/hynb/p/5846406.html