Javascript中的继承

2021-08-30  本文已影响0人  路人丁0417
  1. 原型链继承

    function Person(name, age) {// 父
      this.name = name;
      this.age = age;
    }
    function Student() { // 子
    
    }
    Student.prototype = new Person();
    

    每个构造函数(Person)都有原型对象(prototype),指向Object的实例上的proto属性,Object.Prototype为null
    子类构造函数的prototype指向父类的实例,而父类构造函数的prototype指向Object的实例,通过这种关系,形成了原型链。
    确定原型和实例之间的关系
    a. instanceof操作符
    b. isPrototypeOf()
    Object.prototype.isPrototypeOf(instance) true
    缺点:父子之间共享引用类型的值,不能给父类构造函数传递参数。

  2. 借用构造函数
    在子类的构造函数中调用父类的构造函数,可以避免原型链继承方式中的引用类型值共享的问题,以及不方便向父类构造函数中传递参数的问题(因为可能会影响父类的实例)
    通过call或者apply实现

    function Person(name, age) {// 父
      this.name = name;
      this.age = age;
    }
    function Student(name, age, score) { // 子
      Person.call(this, name, age)
      this.score = score
    }
    

    缺点:在构造函数中定义方法不能实现方法复用

  3. 组合继承
    原型链继承(继承原型上的属性和方法)+借用构造函数(继承实例上的属性)

    function Person(name, age) {// 父
      this.name = name;
      this.age = age;
    }
    function Student(name, age, score) { // 子
      Person.call(this, name, age)
      this.score = score
    }
    Student.prototype = new Person();
    Student.prototype.constructor = Student;
    Student.prototype.sayScore = function() {
      alert(this.score)
    }
    

    缺点:会调用两次父类的构造函数

  4. 原型式继承
    由道格拉斯.克罗克福德提出,基本思想:借助原型可以基于已有的对象创建新对象,同时也不用创建自定义类型。

    function object(o) {
      function F() {}
      F.prototype = o;
      return F()
    }  
    

    ECMAScript5新增Object.create()规范了原型式继承,Object.create(proto[,propertiesObject]),使用现有的对象来提供新创建的对象的proto(来自MDN),返回继承了proto的对象。第二个参数与Object.defineProperties()的第二个参数相同。

    缺点:同原型链继承一样,引用类型的值会共享

  5. 寄生式继承
    同样由道格拉斯.克罗克福德提出,思路与原型式继承紧密相关:创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回对象。

    function createAnother(original) {
      // 也可以用其他方法来创建clone,比如Object.create()
      var clone = object(original);
      clone.sayName = function() {
        alert('hi')
      }
      return clone
    }
    

    缺点:不能函数复用,与借用构造函数类似

  6. 寄生组合式继承(理想的调用方式)
    通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。
    不用调用两次父类的构造函数

function inheritPrototype(subType, superType) {
  var prototype = Object(superType.prototype); // 创建对象
  prototype.constructor = subType;  // 增强对象
  subType.prototype = prototype; // 指定对象
}

function Person() {}
function Student() {
  Person.call(this)
}
inheritPrototype(Student, Person);
上一篇 下一篇

猜你喜欢

热点阅读