js 简单直观的7种继承方式!

123 阅读2分钟

1. class extens --常用

    class Animal {
      constructor (name){
        this.name= name;
      }
      say(){
        console.log("我叫:" + this.name);
      }
      eat(food){
        console.log(this.name + '正在吃:' + food);
      }
    }
    
    class Cat extends Animal{
        constructor(name,age){
          super(name);
          this.age = age;
        }
        getAge(){
          console.log('我叫:'+this.name+";我今年:" + this.age+'岁');
        }
    }
    
    var cat = new Cat("老猫", 1);
    
    cat.say() // 我叫:老猫
    cat.eat("猫粮") // 老猫正在吃:猫粮
    cat.getAge() // 我叫:老猫;我今年:1岁

2. 原型链式继承

   function Animal(name) {
      this.name = name;
      this.say = function () {
        console.log('我叫:'+this.name);
      }
    }
    
    // 原型对象方法
    Animal.prototype.eat = function (food) {
      console.log(this.name + '正在吃:' + food);
    };
    
    function Cat() {}
    
    Cat.prototype = new Animal();
    Cat.prototype.name = '老猫';
    var cat = new Cat();
    
    cat.say() // 我叫:老猫
    cat.eat("猫粮") // 老猫正在吃:猫粮
    console.log(cat.name) // 老猫

3. 构造函数继承

错误的写法- 这么写cat.eat()方法报错:cat.say is undefined;
     // 定义一个父类型
      function Animal (name) { 
      this.name = name;
      this.say = function(){ console.log("我叫:"+ this.name); } 
      } 
      
      // 原型对象方法
      Animal.prototype.eat = function (food) { 
        console.log(this.name + '正在吃:' + food);
      };
      
      function Cat(name,age){
        Animal.call(this,name);
        this.age = age;
      }
      
      var cat = new Cat("老猫",1);
      
      console.log(cat)
      cat.say() // 我叫:老猫
      cat.eat("猫粮") // --报错。
      console.log(cat.name) // 老猫

解析:

5efc3139e9010a035d05269848b85f4.png 关于call的继承不懂的同学可以看看这篇文章:www.cnblogs.com/buildnewhom…

正确写法-或者参照第五点:组合继承
     // 定义一个父类型
      function Animal (name) { 
          this.name = name;
          this.say = function(){ console.log("我叫:"+ this.name); } 
          this.eat = function(food){
               console.log(this.name + '正在吃:' + food);
          }
      } 
      
      function Cat(name,age){
        Animal.call(this,name);
        this.age = age;
      }
      
      var cat = new Cat("老猫",1);
      
      console.log(cat)
      cat.say() // 我叫:老猫
       cat.eat("猫粮") // 老猫正在吃:猫粮
      console.log(cat.name) // 老猫

4. 实例继承

     // 定义一个父类型
      function Animal (name) { 
      this.name = name;
      this.say = function(){ console.log("我叫:"+ this.name); } 
      } 
      
      // 原型对象方法
      Animal.prototype.eat = function (food) {
        console.log(this.name + '正在吃:' + food);
      };
      
      function Cat(name,age){
        var o = new Animal(name); //先创建子类型实例
        o.age = age;
        return o;
      }
        
      var cat = new Cat("老猫",1);
      
      cat.say() // 我叫:老猫
      cat.eat("猫粮") // 老猫正在吃:猫粮
      console.log(cat.name) // 老猫

5. 组合继承

    // 定义一个父类型
    function Animal(name) {
      this.name = name;
      this.say = function () {
        console.log("我叫:" + this.name);
      }
    }
    
    // 原型对象方法
    Animal.prototype.eat = function (food) {
      console.log(this.name + '正在吃:' + food);
    };

    function Cat(name, age) {
      Animal.call(this, name);
      this.age = age
    }

    Cat.prototype = new Animal();
    Cat.prototype.constructor = Cat;

    var cat = new Cat("老猫", 1);
    
    cat.say() // 我叫:老猫
    cat.eat("猫粮") // 老猫正在吃:猫粮
    console.log(cat.name) // 老猫

6. 拷贝继承

    // 定义一个父类型
    function Animal(name) {
      this.name = name;
      this.say = function () {
        console.log("我叫:" + this.name);
      }
    }
    // 原型对象方法
    Animal.prototype.eat = function (food) {
      console.log(this.name + '正在吃:' + food);
    };

    function Cat(name, age) {
      var animal = new Animal(name);
      for (var p in animal) {
        Cat.prototype[p] = animal[p];
      }
      this.age = age
    }

    var cat = new Cat("老猫", 1);

    cat.say() // 我叫:老猫
    cat.eat("猫粮") // 老猫正在吃:猫粮
    console.log(cat.name) // 老猫

7. 寄生组合继承 -- 过于复杂,不实用

     // 定义一个父类型
    function Animal(name) {
      this.name = name;
      this.say = function () {
        console.log("我叫:" + this.name);
      }
    }
    
    // 原型对象方法
    Animal.prototype.eat = function (food) {
      console.log(this.name + '正在吃:' + food);
    };

    function Cat(name, age) {
      Animal.call(this, name);
      this.age = age
    }
    
    (function () { // 创建一个没有实例方法的类
      var Super = function () {};
      Super.prototype = Animal.prototype; //将实例作为子类的原型
      Cat.prototype = new Super();
    })();

    var cat = new Cat("老猫", 1);

    cat.say() // 我叫:老猫
    cat.eat("猫粮") // 老猫正在吃:猫粮
    console.log(cat.name) // 老猫

请教于东神(* ̄︶ ̄)!