JS继承

120 阅读1分钟

1.基于原型链的继承

基本原理是:将父类的实例赋值给子类的原型。

      // 父类
      function Staff() {
        this.company = "huang";
        this.list = [];
      }
      console.dir(Staff);
      // 父类的原型
      Staff.prototype.getComName = function () {
        return this.company;
      };
      console.log(Staff.prototype.__proto__ === Object.prototype);
      // 子类
      function Coder(name, skill) {
        this.name = name;
        this.skill = skill;
      }

      // 继承 Staff
      Coder.prototype = new Staff();

      // 因为子类原型的指向已经变了,所以需要把子类原型的contructor指向子类本身
      Coder.prototype.constructor = Coder;

      // 给子类原型添加属性
      Coder.prototype.getInfo = function () {
        return {
          name: this.name,
          skill: this.skill,
        };
      };

      let coder = new Coder("小明", "javascript");
      console.log(coder.getInfo()); // {name: '小明', skill: 'javascript'}
      console.log(coder.getComName()); // 'huang' 调用的父类原型链上的的方法

这种继承方式的缺点:
子类的实例可以访问父类的私有属性,子类的实例还可以更改该属性,这样不安全。

2. 基于class

class Parent {
        constructor(name) {
          this.name = name;
        }
        static say() {
          return "hello";
        }
      }
      class Child extends Parent {
        constructor(name, age) {
          super(name);
          this.age = age;
        }
      }
      let Child1 = new Child("huang", "22");
      console.log(Child.say());// hello
      console.log(Child1);
  • class 只能通过 new 来调用,而构造函数则可以直接调用;
  • 子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。这是因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工,如果不调用 super 方法,子类就得不到 this 对象。
  • 子类可以继承父类的静态方法。