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
      })
相關文章
相關標籤/搜索