js中的继承模式

继承模式

  • 原型式继承
    • 全部函数的默认原型都是object的实例,这个默认原型对象中有一个指向Object.prototype的指针
    • 判断原型和实例中关系能够经过如下两种方式:
      • instanceof 用来测试实例与原型链中出现过的构造函数的关系,见例子:
        function Super () {
            this.name = 'zhanhui';
            this.say = function () {
                console.log(this.name);
            }
        }
        Super.prototype.getSuper = function () {
            console.log(this);
        }
        function Sub () {
            this.age = 26
            this.howOld = function () {
                console.log(this.age);
            }
        }
        Sub.prototype = new Super(); // 知道new的过程,就知道这里是新建立了一个新的对象
        var obj = new Sub();
        console.log(obj instanceof Object); // true
        console.log(obj instanceof Sub); // true
        console.log(obj instanceof Super); // true
      • isPrototypeOf() 只要是原型链中出现过的原型,均可以说是该原型链所派生的实例的原型,见下列例子:
        Object.prototype.isPrototypeOf(obj); // true
        Sub.prototype.isPrototypeOf(obj); // true
        Super.prototype.isPrototypeOf(obj); // true
      • 谨慎的定义方法,子类有时候须要覆盖超类中某个方法,或者是添加超类中不存在的某个方法,无论如何,给原型添加方法的代码必定要放在替换原型的语句以后,结合上述的例子,见下面代码:
      // 添加新的方法
      Sub.prototype.getSub = function () {
          console.log(true);
      }
      // 覆盖超类中的方法
      Sub.prototype.getSuper = function () {
          console.log(false);
      }
      var obj1 = new Sub();
      Sub.getSuper() // false
      var superObj = new Super();
      superObj.getSuper(); // superObj
  • 组合模式
    • 构造函数内部定义属性,原型上定义方法和共享属性,见例子:
      function Super (name) {
          this.name = name;
          this.friends = ['mike', 'boo']
      }
      Super.prototype.sayName = function () {
          console.log(this.name);
      }
      function Sub () {
          Super.call(this); // 第二次调用超类对象
          this.age = 26;
      }
      Sub.prototype = new Super(); //第一次调用超类对象
      Sub.prototype.constructor = Sub;
      Sub.prototype.sayAge = function () {
          console.log(this.age);
      }
    • 缺点:原型式和构造函数的组合式(缺点:运行两次超类函数,超类函数的属性被挂载在原型对象上和实例对象上)
  • 原型模式
    • Object.create()
  • 寄生式继承
    • 思路:建立一个仅用于封装继承过程的函数,在函数内部来加强对象,添加属性和方法,最后在返回对象,见例子:
      function (original) {
          var clone = Object.create(original); // 建立的新对象的__proto__指向original
          clone.say = function () {
              console.log(true);
          }
          return clone;
      }
  • 构造函数
  • 寄生组合模式(主要是解决上述模式中调用两次超类构造函数),这个是引用类型最理想的继承方式
    • 见例子:
      function superObj (name){
      this.name = name;
      this.firends = [1,2,3];
      }
      superObj.prototype.say = function(w) {
      console.log(w);
      };
      function subObj (name) {
      superObj.call(this,name);
      }
      subObj.prototype = Object.assign(Object.create(superObj.prototype),{
      constructor: subObj
      })
相关文章
相关标签/搜索