1、原型继承

  1. function Animal() {
  2. this.color = ['black','white']
  3. }
  4. Animal.prototype.getColor = function(){
  5. return this.color
  6. }
  7. function Dog() {}
  8. Dog.prototype = new Animal()
  9. let dog1 = new Dog()
  10. dog1.colors.push('brown')
  11. let dog2 = new Dog()
  12. console.log(dog2.colors)

原型链继承存在的问题:

  • 问题1:原型中包含的引用类型属性将被所有实例共享;
  • 问题2:子类在实例化的时候不能给父类构造函数传参;

    2、借用构造函数实现继承

    1. function Animal(name) {
    2. this.name = name
    3. this.getName = function () {
    4. return this.name
    5. }
    6. }
    7. function Dog(name) {
    8. Animal.call(this, name)
    9. }
    10. Dog.prototype = new Animal()

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

3、组合继承

  1. function Animal(name) {
  2. this.name = name
  3. this.colors = ['black', 'white']
  4. }
  5. Animal.prototype.getName = function () {
  6. return this.name
  7. }
  8. function Dog(name, age) {
  9. Animal.call(this, name)
  10. this.age = age
  11. }
  12. Dog.prototype = new Animal()
  13. Dog.prototype.Constructor = Dog
  14. let dog1 = new Dog('奶昔', 2)
  15. dog1.colors.push('brown')
  16. let dog2 = new Dog('哈赤', 1)
  17. console.log(dog2)

优点:融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。
缺点:调用了两次构造函数,做了重复的操作。

4、寄生组合继承

  1. // 原型链继承 + 构造函数继承
  2. // 1. 引用类型被改变,所有实例共享
  3. // 2. 无法传参
  4. // 3. 多占用了内存空间
  5. function Parent(name, actions) {
  6. this.name = name;
  7. this.actions = actions;
  8. }
  9. Parent.prototype.getName = function () {
  10. console.log(this.name + '调用了getName');
  11. }
  12. function Child() {
  13. Parent.apply(this, arguments);
  14. }
  15. // Child.prototype = Parent.prototype; // 一旦更改Child.prototype,Parent.prototype也会被修改。
  16. Child.prototype = Object.create(Parent.prototype);
  17. // Child.prototype = new Parent();
  18. // let TempFunction = function () {};
  19. // TempFunction.prototype = Parent.prototype;
  20. // Child.prototype = new TempFunction();
  21. Child.prototype.constructor = Child;
  22. // super() Child
  23. const c1 = new Child('c1', ['eat']);
  24. const c2 = new Child('c2', ['run']);