js中的继承方式

116 阅读2分钟

1.原型链继承

        function Parent(name,age){
            this.colors=['blue','green','red'];
        }
        Parent.prototype.getColors=function(){
            return this.colors;
        }
        function Child(){};
        Child.prototype=new Parent();
        var child1=new Child();
        child1.colors.push('yellow');
        var child2=new Child();
        console.log(child2.colors); // blue,green,red,yellow

优点: 可以继承构造函数和原型上的属性和方法。

问题:

  1. 原型链中包含的引用数值类型被所有实例共享
  2. 子类在实例化的时候不能给父类构造函数传递参数。
2.构造函数继承
        function Super1Type(name) {
            this.name = name;
        }
        function Sub1Type() {
            Super1Type.call(this, 'shuaina');
            this.age = 25;
        }
        let instances = new Sub1Type();
        console.log(instances.name);

借用构造函数实现继承解决了原型链继承的 2 个问题:引用类型共享问题以及传参问题。但是由于方法必须定义在构造函数中,所以会导致每次创建子类实例都会创建一遍方法。

3.组合继承
        function Animal(name){
           this.name=name;
           this.colors=['red','blue','green'];
       }
       Animal.prototype.getName=function(){
           return this.name;
       }
       function Dog(name,age){
           Animal.call(this,name);
           this.age=age;
       }
       Dog.prototype=new Animal();
       var dog1=new Dog('shuai',25);
       dog1.colors.push('white');
       var dog2=new Dog('wang',18);
       console.log(dog2);

组合继承结合了原型链和盗用构造函数,将两者的优点集中了起来。基本的思路是使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实例属性。这样既可以把方法定义在原型上以实现重用,又可以让每个实例都有自己的属性。 问题:调用了两次构造函数

4.寄生式组合继承

组合继承已经相对完善了,但还是存在问题,它的问题就是调用了 2 次父类构造函数,第一次是在 new Animal(),第二次是在 Animal.call() 这里。 所以解决方案就是不直接调用父类构造函数给子类原型赋值,而是通过创建空函数 F 获取父类原型的副本。

     function object(o){
        function F(){};
        F.prototype=o;
        return new F();
    }
    function inheritPrototype(child,parent){
        let prototype=object(parent.prototype);
        prototype.constructor=child;
        child.prototype=prototype;
    }
    function Animal(name){
           this.name=name;
           this.colors=['red','blue','green'];
       }
       Animal.prototype.getName=function(){
           return this.name;
       }
       function Dog(name,age){
           Animal.call(this,name);
           this.age=age;
       }
       var dog1=new Dog('shuai',25);
       dog1.colors.push('white');
       var dog2=new Dog('wang',18);
       console.log(dog2);

5.class实现继承

    class Animal{
       constructor(name){
           this.name=name;
       }
       getName(){
           return this.name;
       }
   }
   class Dog extends Animal{
       constructor(name,age){
           super(name);
           this.age=age;
       }
   }