首页 > 技术文章 > js继承

ghostdot 2019-08-20 14:34 原文

原型讲解

普通对象只有__proto__属性指向其原型对象,只有构造函数构本体才具有Prototype属性
js的原型,每个构造函数都有一个原型对象,原型对象里面有一个指针constructor指向构造函数
每个示列里面都有一个__proto__指向原型对象, 从一个实列里找到他构造函数的原型对象,该原型对象又有构造他的原型对象__proto__
这样就形成了一条原型链。原型链的最顶端是Object.prototype.


         function Person(){ //原型对象为Person.prototype
            this.age = 20
         }
         console.log(Person.prototype.constructor ==Person) //原型对象里面有一个指针constructor指向构造函数Person
         var person = new Person()
        //  person.say() //person里面有一个__proto__属性指向构造他的原型对象
        console.log(person.__proto__ === Person.prototype) 
        //分析:person(__proto__) ----> Person.prototype(constructor) ---> Person 这就是原型关系
        //原型链
        GranFather.prototype.lastName = 'ghost'
        GranFather.prototype.say = function(){
            console.log(this.name) //谁调用this指向谁
        }
        function GranFather(){
            

        }
        var grand = new GranFather()
        Father.prototype = grand
        function Father(){
          this.name="charry";
          this.money = 100;
       

        }
        var father = new Father()
        Son.prototype = father
        function Son(){
            this.age = 20
            this.name ="liejian"
        }
        function daughter(){
           this.age =10
           this.name = 'mianmian'
        }
        var son = new Son()
        console.log(son.lastName) //ghost
        console.log(son.money) //100
        console.log(son.name) //liejian
        son.say() //liejian

继承

1 原型链继承

        function Father(){
             this.name = 'ghost',
             this.age = 18,
             this.say = function (){
                 console.log(this.name)
             }
        }
        var father = new Father()
        Son.prototype = father
        function Son(){
            this.age = 30 
        }
        var son = new Son()
       son.say() //__proto__ --->father 缺点:继承了过多没有用的属性

2 call/apply继承

      function Father(name, age ,sex){
          this.name = name;
           this.age = age;
           this.sex = sex;

      }
      function Son(name, age, sex, tel, grade){
          Father.call(this, name, age, sex);
          this.tel = tel;
          this.grade = grade;
      }
      var son = new Son('ghost', '18', '20', '18208891933', 100)
      console.log(son.name) //ghost 调用Father这个工厂来生成, 所以不算标准继承, 每次继承要多走一个函数浪费性能

3 共享原型继承

      function Father(){
        
      }
      function Son(){

      }
      Father.prototype.name = 'ghost'
      Son.prototype = Father.prototype;
      Son.prototype.age = 20;
      var son = new Son()
      console.log(son.name) //ghost
      console.log(son.age) //20 共享原型继承的缺点是不能随便改动自己的原型,因为原型是一个对象存放的是引用值
      var father = new Father()
      console.log(father.age) //20 污染father

4 圣杯模式继承(最推荐使用的一种继承方法)

       function Father(){

       }
       function F(){
           name:'charry'

       }
       function Son(){

       }
       Father.prototype.name = 'ghost'
       F.prototype.name = 'charry'
       var f = new F()
       Son.prototype = f
      var father = new Father()
      console.log(father.name) //ghost
      var son = new Son()
      console.log(son.name) //charry
      //son.__proto__ -->f--->f.proto--->Father.prototype

5 封装圣杯继承的方法

      function inherit(target, origin){
         function F(){}
         F.prototype = origin.prototype;
          target.prototype = new F()
          target.constructor = target
      }
      inherit(Son, Father)
    var son = new Son()
    console.log(son.name)

推荐阅读