JS继承的6种方式

Posted 程嘿嘿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS继承的6种方式相关的知识,希望对你有一定的参考价值。

定义一个父类Person:

function Person(name){
    this.name=name;
}
Person.prototype.age=25;
Person.prototype.show=function(){
  console.log(this.name);
}

 

1.原型链继承

子类的原型是父类的实例。

function subType(){}
subType.prototype=new Person();

// 测试
let p1=new subType();
p1.name;    //undefined,可以访问,但是name未初始化所以为undefined
p1.age;    //25

特点:父类的构造函数中的属性和方法,以及原型中的属性和方法都放入了子类的原型中,都可以访问得到。

问题:

1.原型中的属性和方法,在实例中是共享的。构造函数中的属性和方法在实例中不共享。这说明,父类中的所有属性,在子类的实例中都将共享,假如父类有一个数组,那么子类的实例将共享这个属性,当有一个子类实例改变这个数组的项时,所有的实例中的这个属性都会随之改变。

2.创建子类实例时,不能向超类型构造函数中传递参数。

 

2.借用构造函数

在子类构造函数中调用父类构造函数。

function subType(name){
    Person(this,name);
}

// 测试
let p2=new subPerson("zhangsan");
p2.name;    //"zhangsan"
p2.age;    //undefined

特点:解决了方法一的问题,所有的子类实例都将不共享属性和方法,互不影响,并且可以传值。

问题:

1.构造函数中的方法不能共享复用,每个实例都将拥有相同的方法。

2.父类的原型中的方法和属性在子类中不可见。

 

3.组合继承

组合原型链方法和借用构造函数方法

function subType(name){
    Person.call(this,name);
}
subType.prototype=new Person();

//测试
let p3=new subType("lisi");
p3.name;    //"lisi"
p3.show();    //"lisi"
p3.age;    //25

特点:既可以继承父类原型中的属性和方法,又能将父类的构造函数放入子类构造函数中。

 

4.原型式继承

以一个对象为基础,创建一个新对象,并将旧对象作为新对象的原型,返回这个新对象的实例。

function subType(o){
    function fn(){};
    fn.prototype=o;
    return new fn();
}

//测试
let person=new Person("wangwu");
let p4=subType(person);
p4.name;    //"wangwu"
p4.age;    //25

特点:要求必须有一个对象可以作为另一个对象的基础。返回的是一个对象。

缺点:和原型链方式一样,父类的属性会共享。

 

5.寄生式继承

构造函数中通过某种方式创建父类对象,然后为这个对象添加属性和函数,并返回这个对象。

function clone(o){
    function fn(){};
    fn.prototype=o;
    return new fn();
}
function subType(original){
    let obj=clone(original);
    obj.sayHi=function(){
        alert("Hi");
    }
}

特点:创建对象部分不必要固定方式,只要可以返回一个父类对象就可。返回的是一个加入了自定义方法和属性的对象。

缺点:方法不能共享复用。

 

6.寄生组合式继承

使用寄生式继承来继承超类型的原型。使用接用构造函数的方法继承父类的构造函数属性和方法,并添加自己的构造函数属性和方法。

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

function inheritPrototype(subType,superType){
    let p=object(superType.prototype);
    p.constructor=subType;
    subType.prototype=p;
}

//子类
function subType(name){
    Person.call(this,name);
}
inheritPrototype(subType,Person);

特点:避免了组合式继承中原型和构造函数中重复继承父类的构造函数中的属性和方法。

以上是关于JS继承的6种方式的主要内容,如果未能解决你的问题,请参考以下文章

JS继承的6种方式

理解js继承的6种方式

JS继承的6种方式

js的6种继承方式

重新理解JS的6种继承方式

重新理解JS的6种继承方式(转)