原型与继承

原型
  • 概念
    • 每个对象都有自己的prototype属性,称为原型对象,如果原型对象不为null,那么这个原型对象里面有一个__proto__属性会指向自己的原型,此时就产生了原型链
  • 作用
    • 把一些方法定义在prototype对象上,这样所有对象的实例就可以共享这些方法,节约内存
继承
  • 构造函数继承 (实现对实例属性的继承)
    • 通过call() 或者apply()方法改变父构造函数的this

    •     function Father() {
              this.head = '头'
              this.foot = '脚'
              this.say = function () {
                  console.log('hello');
              }
          }
          function Son(name, age) {
              this.name = name
              this.age = age
              Father.call(this)  // 用call继承Father
          }
          const son = new Son('刘德华', 18)
          son.say() //hello
          console.log(son.name); //刘德华
          console.log(son.age);  //18
          console.log(son.head); //头
          console.log(son.foot); //脚
      
  • 通过原型链的方式继承 (实现对原型对象属性和实例属性的继承)
    •     function Father() {
              this.head = '头'
              this.foot = '脚'
          }
           Father.prototype.say = function () {
              console.log('hello');
          }
          function Son(name, age) {
              this.name = name
              this.age = age
          }
          Son.prototype = new Father() //用原型链的方式,子类的原型对象=父类的的实例,此方法会导致子类原型的constructor丢失,所以需要手动添加constructor
          Son.prototype.constructor = Son  //把原型对象指回Son
          const son = new Son('刘德华', 18)
          son.say() //hello
          console.log(son.name); //刘德华
          console.log(son.age);  //18
          console.log(son.head); //头
          console.log(son.foot); //脚
      
      
  • 通过原型直接继承 (实现对原型对象属性的继承,会造成原型链混乱,所以进行特殊处理)
    • function Father() {
       this.hand = '手'
      }
       Father.prototype.head = '头'
       Father.prototype.foot = '脚'
       Father.prototype.say = function () {
           console.log('hello');
       }
       function Son(name, age) {
           this.name = name
           this.age = age
       }
       //原始的做法  Son.prototype = Father.prototype
       //优点:比较节约内存 不用new一个Father实例对象 
       //缺点:会造成继承链的混乱 即Son.prototype.constructor
       //与Son.prototype.constructor相等,这样是不合理的
       //所以可以进行封装 解决混乱问题
       function extend(Child, Parent) {
           const F = function () { }  //1搞一个空对象
           F.prototype = Parent.prototype //2空对象作为中介来接收父类的原型对象
           Child.prototype = new F()  //3子类通过new这个空对象实例间接继承父类
           Child.prototype.constructor = Child //4子类指回自身构造函数
       }
         
       extend(Son, Father) //直接调用封装好的继承函数
       const son = new Son('刘德华', 18)
       son.say() //hello
       console.log(son.name); //刘德华
       console.log(son.age);//18
       console.log(son.head); //头
       console.log(son.foot); //脚
       console.log(son.hand); //undefined  
      
  • 组合继承 (实现对原型对象属性和实例属性的继承)
    • 把构造函数继承和原型链继承相结合

    • function Father() {
            this.head = '头'
        }
        Father.prototype.hobby = function () {
            console.log('喝酒');
      
        }
        function Son(name) {
            Father.call(this)
            this.name = name
        }
        Son.prototype = new Father()
        Son.prototype.constructor = Son
        const son = new Son('刘德华')
        console.log(son.name); //刘德华
        console.log(son.head); //头
        son.hobby()  //喝酒
      
  • 拷贝继承(实现原型对象属性的继承)
    • function Father() {
           this.head = '头'
       }
       Father.prototype.hobby1 = '喝酒'
       Father.prototype.hobby2 = '抽烟'
         
       function Son(name) {
           this.name = name
       }
         
       Object.assign(Son.prototype, Father.prototype)
       const son = new Son('刘德华')
       console.log(son.name); //刘德华
       console.log(son.hobby1);//喝酒
       console.log(son.hobby2);//抽烟
       console.log(son.head); //undefined
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值