第六章(3):继承

作者: 日暮途远_ | 来源:发表于2017-07-25 18:40 被阅读20次

    继承的几种方式

    • 原型链
     /**
       * 原型链继承
       * 本质是重写原型对象
       * 缺点:引用类型值被实例共享
         * @constructor
         */
      function Super() {
        this.property = 'super'
        this.arr = [1,2]
      }
    
      Super.prototype.getValue = function () {
        return this.property
      }
    
      function Sub() {
    
      }
    
      Sub.prototype = new Super();
    
      let sub = new Sub()
      console.log(sub.getValue())  // super
    
      console.log(Super.prototype.isPrototypeOf(sub)) // true
      console.log(Sub.prototype.isPrototypeOf(sub)) // true
      console.log(Object.prototype.isPrototypeOf(sub)) // true
    
      let sub1 = new Sub()
      sub1.arr.push(3);
    
      let sub2 = new Sub()
      console.log(sub1.arr) // [1,2,3]
      console.log(sub2.arr) // [1,2,3]
    

    原型链示意图:

    • 构造函数
    /**
       * 借用构造函数模式
       * 问题:函数无法复用
         * @constructor
         */
        function SuperInstance() {
        this.color = ['red', 'yellow']
      }
    
      function SubInstance() {
        SuperInstance.call(this)
      }
    
      var si = new SubInstance();
        var si1 = new SubInstance();
    
        si.color.push("black");
        console.log(si.color) //  ["red", "yellow", "black"]
        console.log(si1.color)  //  ["red", "yellow"]
    
    • 组合继承(将原型链和构造函数组合在一起)
    /**
       * 组合模式继承
       * 最常用的模式
         * @param name
         * @constructor
         */
      function SuperCombination(name) {
            this.name = name;
        this.color = ['red', 'yellow'];
      }
    
      SuperCombination.prototype.getName = function () {
        return this.name;
      }
    
      function SubCombination(name, age) {
        SuperCombination.call(this, name)
        this.age = age
      }
    
      SubCombination.prototype = new SuperCombination();
    //  SubCombination.prototype.constructor = SubCombination;
    
      SubCombination.prototype.sayAge = function () {
        return this.age;
      }
    
      let sc = new SubCombination('日暮途远', 18);
      let sc1 = new SubCombination('Tiptoe', 20);
    
      sc.color.push('black');
    
      console.log(sc.color, sc.getName(), sc.sayAge()) // ["red", "yellow", "black"] "日暮途远" 18
      console.log(sc1.color, sc1.getName(), sc1.sayAge()) //  ["red", "yellow"] "Tiptoe" 20
    
    • 原型式继承
        /**
         * 原型式继承
         * 缺点: 引用类型共享
         * @type {{name: string, sayName: person.sayName, game: [string,string]}}
         */
        var person = {
            name: '日暮途远',
            sayName: function () {
                return this.name;
            },
            game: ['英雄联盟', '王者荣耀']
        }
    
        var o = Object.create(person);
        console.log(o.sayName()); // 日暮途远
    
        o.game.push('战地')
        console.log(person.game)  // ["英雄联盟", "王者荣耀", "战地"]
    
    • 寄生式组合继承
    /**
       * 寄生组合式继承
       * 优点:避免2次调用父类构造函数
         * @param subType
         * @param superType
         */
      function inherit(subType, superType) {
        var property = Object.create(superType.prototype);
        property.constructor = subType;
        subType.prototype = property;
      }
    
      function SuperIn(name) {
        this.name = name
      }
    
      SuperIn.prototype.sayName = function () {
        return this.name;
      }
    
      function SubIn(name, age) {
        SuperIn.call(this, name)
        this.age = age
      }
    
      inherit(SubIn, SuperIn)
    
      SubIn.prototype.sayAge = function () {
        return this.age;
      }
    
      let sI = new SubIn('日暮途远', 18)
      console.log(sI.sayName()) // 日暮途远
    

    引用

    javascript高级程序设计第三版

    相关文章

      网友评论

        本文标题:第六章(3):继承

        本文链接:https://www.haomeiwen.com/subject/kvlgkxtx.html