ES5 继承方式

1、原型链继承

function A(name) {
    this.name = name
}

A.prototype.getName = function() {
    return this.name
}

function B() {
    this.bName = "L"
}

B.prototype = new A("H");
let b = new B();

  优点:实现比较简单,能通过instanceOf和isPrototypeOf的检测。

      缺点:1. 在通过原型链实现继承时,原型实际上会成为另一个类型的实例, 父类的实例属性实际上会成为子类的原型属性。结果就是所有的子类的实例都会共享父类的实例属性(引用类型的)。
         2. 在创建子类型的实例时,没有办法在不影响所有实例的情况下,向父类型的构造函数传递参数。因此实践中很少单独使用原型链继承。

  

2、构造函数继承

function A(name) {
    this.name = name
}

function B(nameParam) {
    A.call(this, nameParam)
}

let b = new B("H");

      优点:可以向父类构造函数传参数,并且每一个子类实例都有父类属性和方法的副本
      缺点:正是因为这种方法调用父类,所以也只能继承父类的属性和方法,且继承的方法也无法复用。并且不能继承父类原型的属性和方法。(子类原型并未链接父类原型)

 

3、组合继承

function A(name) {
    this.name = name
}
A.prototype.getName = function() {
    return this.name;
}

function B(nameParam, ageParam) {
    A.call(this, nameParam);
    this.age = ageParam;
}

B.prototype = new A("H");
let b = new B("L", 23);

      优点:组合继承避免了原型链和借用构造函数的缺陷。融合了他们的优点成为JavaScript中最常用的继承模式。而且instanceof 和 isPrototypeOf() 也能够用于识别基于组合继承创建的对象。
      缺点:组合继承调用了两次父类,因此子类实例和子类的原型上各存有一份父类实例的属性和方法。

 

4、原型式继承

function A(obj) {
    function fn() {}
    fn.prototype = obj
    return new fn()
}

let b = {
    name: "H",
    play: function() {
        console.log(`${this.name} is playing`);
    }
}

let c = new A(b);

  优点:在没有必要兴师动众的创建构造函数,而只想让一个对象与另外一个对象保持类似的情况下,原型式继承是完全可以胜任的。

      缺点:包含引用类型值的属性始终都会共享相同的值,并且这种方法有局限性。

 

5、寄生继承

function A(obj) {
    function fn() {};
    fn.prototype = obj;
    return new fn();
}

function generate(people) {
    let b = A(people);
    b.getName = function() {
        console.log(`His name is ${this.name}`)
    }
    return b;
}

let p = {
    name: "H",
    play: function() {
        console.log(`${this.name} is playing`)
    }
}

let b = generate(p);

  优点:在主要考虑对象,而不是自定义类型和构造函数的情况下,寄生式继承也是一种可选方案。

      缺点:和原型继承类似有一定局限性。

 

6、寄生组合式继承

function A(name) {
    this.name = name
}
A.prototype.getName = function() {
    console.log(`His name is ${this.name}`)
}

function B(nParam, aParam) {
    A.call(this, nParam);
    this.age = aParam;
}

function generate(Parent, Child) {
    let proto = Object.create(Parent.prototype);
    proto.constructor = Child;
    Child.prototype = proto;
}

generate(B,A);
let c = new B()

  

new:

{
    var obj = {};
    var res = func.call(obj);
    return typeof res ==="Object"? res: obj;
}

Object.create:

{
    function fn() {};
    fn.prototype = obj;
    return new fn();
}
posted @ 2021-03-10 12:05  console.log('宇航')  阅读(117)  评论(0编辑  收藏  举报